Scilab Home Page | Wiki | Bug Tracker | Forge | Mailing List Archives | Scilab Online Help | File Exchange
ATOMS : Image Processing and Computer Vision Toolbox details
Login with GitLab

Image Processing and Computer Vision Toolbox

A Module of Image Processing and Computer Vision Toolbox for Scilab
(2968 downloads for this version - 251133 downloads for all versions)
Details
Version
4.5.0
Author
Tan Chin Luh
Maintainers
Vincent COUVERT
Chin Luh Tan
Stéphane MOTTELET
Category
License
Creation Date
November 29, 2023
Source created on
Scilab 2024.0.x
Binaries available on
Scilab 2024.0.x:
Windows 64-bit macOS Linux 64-bit
Install command
--> atomsInstall("IPCV")
Description
            IPCV – Scilab Image Processing & Computer Vision, a module of Image
Processing and Computer Vision Toolbox for Scilab. Topics covered shown as
below, for details check out the functions summary in the download section.

•	Analytic Geometry 
•	Camera Handling 
•	Deep Learning 
•	Feature Detection, Description and Matching 
•	Filter Design and Visualization 
•	Image Analysis and Statistics 
•	Image Arithmetic 
•	Image Block Processing 
•	Image Enhancement and Restoration 
•	Image Linear Filtering 
•	Image Reading, Display and Exploration 
•	Image Registration and Image Fusion 
•	Image Stitching 
•	Image Transforms 
•	Image Types and Color Space Conversions 
•	Morphological Operations 
•	Object Detection 
•	Object Tracking 
•	ROI Processing 
•	Spatial Transformations 
•	Structural Analysis and Shape Descriptors 
•	Super Resolution 
•	Utilities and Interactive Tools 
•	Video Handling 

Updates on 4.1.2 (2019-11-15)
•	Deep learning inference = support for ONNX model 
•	Preparing support for upcoming module to integrate with libTorch (pytorch) 
•	Update lib to OPENCV 4.1.2

Version 4.5 (21-Nov-23):
• Change OpenCV Dependency to 4.5
• base64toimg, imgtobase64 (20-Sep-2022) - experimental, requite USB E for
image exchange

            
Files (4)
[98.77 MB]
Windows 64-bit binary for Scilab 2024.0.x

[13.82 MB]
Source code archive

[87.58 MB]
macOS binary for Scilab 2024.0.x

[74.25 MB]
Linux 64-bit binary for Scilab 2024.0.x

News (5)
Comments (9)     Leave a comment 
Comment from Yukiya Kawakami -- December 1, 2023, 10:57:06 AM    
Hi,

I'd like to report that I found bugs in the " case 'log' " part in
fspecial.sci.

case 'log'
wrong:
        x2 = ones(siz(1),1) * ([-sizx:sizx]^2);
        y2 = ([-sizy:sizy]^2)' * ones(1, siz(2));
correct:
        x2 = ones(siz(1),1) * ([-sizx:sizx].^2);
        y2 = ([-sizy:sizy].^2)' * ones(1, siz(2));

I checked the difference between "case 'gaussian' " part and "case
'log' " part.
So, two "."(s) disappeared in the "case 'log' " part. These
are what I found.

Y. Kawakami
Answer from Stéphane MOTTELET -- December 1, 2023, 12:06:24 PM    
> Hi,
> 
> I'd like to report that I found bugs in the " case 'log' "
part
> in fspecial.sci.
> 
> case 'log'
> wrong:
>         x2 = ones(siz(1),1) * ([-sizx:sizx]^2);
>         y2 = ([-sizy:sizy]^2)' * ones(1, siz(2));
> correct:
>         x2 = ones(siz(1),1) * ([-sizx:sizx].^2);
>         y2 = ([-sizy:sizy].^2)' * ones(1, siz(2));
> 
> I checked the difference between "case 'gaussian' " part and
> "case 'log' " part.
> So, two "."(s) disappeared in the "case 'log' " part.
> These are what I found.
> 
> Y. Kawakami

Hello,

The dots did not dissapear, there were never present. However, since 2024.0 version Scilab
does not accept using the power operator on non-square matrices. I did not have time to
review all macros so thanks for the report.
Comment from Alain Lamy -- January 22, 2024, 12:30:45 PM    
Hello, 

imread returns a NxM matrix if the image is grayscale (otherwise it returns a NxMx3 
matrix). 

But the test is (see imread) : 
if (sum(S==0)+sum(S==255)) == prod(size(S)) then <convert to 2D matrix> 

which means that S(i,j,k) is either 0 or 255. 

But this condition does not mean "grayscale": "blue",
"green", "yellow", etc meet the 
condition. 

Alain
Answer from Yukiya Kawakami -- February 5, 2024, 09:16:31 AM    
> Hello, 
> 
> imread returns a NxM matrix if the image is grayscale (otherwise it returns a NxMx3 
> matrix). 
> 
> But the test is (see imread) : 
> if (sum(S==0)+sum(S==255)) == prod(size(S)) then <convert to 2D matrix> 
> 
> which means that S(i,j,k) is either 0 or 255. 
> 
> But this condition does not mean "grayscale": "blue",
> "green", "yellow", etc meet the 
> condition. 
> 
> Alain

Hi, Alain Lamy,
I haven't seen what you wrote, a long time.
But I see it now.
So, I feel it needs easy example.

Example script for Scilab is here.

  S=zeros(15,15);
  S( 1:5,  1:5, 1)=255;
  S( 6:10, 6:10,2)=255;
  S(11:15,11:15,3)=255;
  S=uint8(S);
  imshow(S); 
  mprintf('sum(S==0)+sum(S==255)=%d\n',sum(S==0)+sum(S==255));
  mprintf('prod(size(S))=%d\n',prod(size(S)));

  imwrite(S, PWD+'RGB_test.png');

  S2 = imread(PWD+'RGB_test.png');
  scf;
  imshow(S2);

The picture of S2 is different from that of S.
Where does this come from?
The imread.sci of IPCV has the part (what Alain Lamy has already written),

    if (sum(S==0)+sum(S==255)) == prod(size(S)) then
        if size(S,3) == 4;
            S = S(:,:,1:3);
        end
        S = im2bw(S,0.5);
    end

My idea for its fix is follows,

    if size(S,3)==1 | (S(:,:,1)==S(:,:,2) & S(:,:,2)==S(:,:,3)) then  
      if (sum(S(:,:,1)==0)+sum(S(:,:,1)==255)) == prod(size(S(:,:,1))) then
          if size(S,3) == 4;
              S = S(:,:,1:3);
          end
          S = im2bw(S,0.5);
      end
    end

I confirmed this fix works well with the above example script.

Maybe there is better fix.
Yukiya Kawakami
Comment from Yukiya Kawakami -- January 31, 2024, 09:42:52 AM    
Hi, Stéphane MOTTELET

Thank you for your reply.


I saw the SIVP macro and confirmed same condition (two dots were missing). 

Now, I have 3 suggestions for fspecial.sci/bin.
Comment from Yukiya Kawakami -- January 31, 2024, 09:43:51 AM    
First suggestion is the modification for ‘average’ that is match with the page of
help-
browser.

That says “hsize can be a 1x2 vector which indicates the rows and columns of F.” 
However, it is unavailable now.

The main modified body that is match with above description, is below,

 

    case 'average' then,

        if length(varargin)>1 then, 

            error("Too many arguments for this kind of filter");

        end

        if isempty(op1) then, 

            op1=3; 

        else

            if op1 ~= floor(op1) then, error('The second argument must be an
integer.'); 
end;

        end

        

        if length(op1)==1 then

           F = ones(op1,op1);

        elseif length(op1)==2 then

           F = ones(op1(1),op1(2));

        else

           error("The second argument should have 1 or 2 elements for average
filter");

        end


        sumF=sum(F);

        if sumF~=0 then

            F = F / sum(F);

        end
Comment from Yukiya Kawakami -- January 31, 2024, 09:45:17 AM    
Second suggestion is adding the item ‘disk’.


The comment is below,


    // <varlistentry>

    //    <term>F = fspecial('disk', radius) : </term>

    //    <listitem>returns a circular averaging filter (pillbox) within the square
matrix 
of side 2*radius+1. The default radius is
5.</listitem>

    // </varlistentry>

 

The original code for Matlab is 
https://github.com/alexandrovteam/IMS_quality/blob/master/codebase/fspecialIM.m

I tweaked it for IPCV and removed imaginary part of kernel (F).

The main body is below,

 

    case 'disk' then,

        if length(varargin)>1 then, 

            error("Too many arguments for this kind of filter");

        end

        if isempty(op1) then, 

            op1=5; // op1 is radius in this CASE.

        else

            if op1 ~= floor(op1) then, error('The second argument must be an
integer.'); 
end;

        end

 

        op2  = ceil(op1-0.5);

        [x,y] = meshgrid(-op2:op2,-op2:op2);

        maxxy = max(abs(x),abs(y));

        minxy = min(abs(x),abs(y));

        m1 = (op1^2 <  (maxxy+0.5).^2 + (minxy-0.5).^2).*(minxy-0.5) + ...

          (op1^2 >= (maxxy+0.5).^2 + (minxy-0.5).^2).* ...

                 sqrt(op1^2 - (maxxy + 0.5).^2);

        m2 = (op1^2 >  (maxxy-0.5).^2 + (minxy+0.5).^2).*(minxy+0.5) + ...

          (op1^2 <= (maxxy-0.5).^2 + (minxy+0.5).^2).* ...

           sqrt(op1^2 - (maxxy - 0.5).^2);

        F = (op1^2*(0.5*(asin(m2/op1) - asin(m1/op1)) + ...

           0.25*(sin(2*asin(m2/op1)) - sin(2*asin(m1/op1)))) - ...

           (maxxy-0.5).*(m2-m1) + (m1-minxy+0.5)) ... 

                    .*((((op1^2 < (maxxy+0.5).^2 + (minxy+0.5).^2) & ...

           (op1^2 > (maxxy-0.5).^2 + (minxy-0.5).^2)) | ...

                 ((minxy==0)&(maxxy-0.5 < op1)&(maxxy+0.5>=op1))));

                  F = real(F);

        F = F + ((maxxy+0.5).^2 + (minxy+0.5).^2 < op1^2);

        F(op2+1,op2+1) = min(%pi*op1^2,%pi/2);

        if ((op2>0) & (op1 > op2-0.5) & (op1^2 < (op2-0.5)^2+0.25)) then

            m1  = sqrt(op1^2 - (op2 - 0.5).^2);

                      m1n = m1/op1;

            f0 = 2*(op1^2*(0.5*asin(m1n) + 0.25*sin(2*asin(m1n)))-m1*(op2-0.5));

            f0 = real(f0);

            F(2*op2+1,op2+1) = f0;

            F(op2+1,2*op2+1) = f0;

            F(op2+1,1)       = f0;

            F(1,op2+1)       = f0;

            F(2*op2,op2+1)   = F(2*op2,op2+1) - f0;

            F(op2+1,2*op2)   = F(op2+1,2*op2) - f0;

            F(op2+1,2)       = F(op2+1,2)      - f0;

            F(2,op2+1)       = F(2,op2+1)      - f0;

        end

        F(op2+1,op2+1) = min(F(op2+1,op2+1),1);

 

        sumF=sum(F);

        if sumF~=0 then

            F = F / sum(F);

        end
Comment from Yukiya Kawakami -- January 31, 2024, 09:47:07 AM    
Third suggestion is adding the item ‘scharr’.


The comment is below,


    // <varlistentry>

    //    <term>F = fspecial('scharr') : </term>

    //    <listitem>returns a 3x3 horizontal edges scharr filter. If you want a
vertical 
edges scharr filter, you can use
transposition of F. F is [ 3 10 3; 0 0 0; -3 -10 -3].</listitem>

    // </varlistentry>


The main body is below,

    case 'scharr' then,

        if length(varargin)>0 then, 

            error("Too many arguments for this kind of filter");

        end

        F=[3 10 3; 0 0 0; -3 -10 -3];


If fspecial() contaions this "scharr", it is available for edge.sci. But it needs
to be 
modified.
Comment from Yukiya Kawakami -- January 31, 2024, 09:48:50 AM    
I tried the following macro with changed fspecial.bin above,  and it worked.


         im = imread(fullpath(getIPCVpath() + "/images/baboon.png"));

         imshow(im); gcf().info_message = 'original';

          scf;

          filter = fspecial('sobel');

          imf = imfilter(im, filter);

          imshow(imf); gcf().info_message = 'sobel';

          scf;

          filter = fspecial('scharr');

          imf = imfilter(im, filter);

          imshow(imf); gcf().info_message = 'scharr';

          scf;

          imf = imfilter(im, fspecial('average',[5,3]));

          imshow(imf); gcf().info_message = 'average';

          scf;

          imf = imfilter(im, fspecial('disk',5));

          imshow(imf); gcf().info_message = 'disk';
 

I hope this helps.

Yukiya Kawakami
Comment from Matthias Lehmann -- February 5, 2024, 04:18:10 PM    
Hi,

I fear that either the RGB to HSV conversion is flawed or at least the help contents are
wrong. I'm using rgb2hsv, I would expect the result to be in the order H, then S, then
V. I did some sample conversions and cross-checked against an online color-picking tool,
specifically this one: https://colorpicker.me/#6464fa.
If I'm converting RGB 255 / 255 / 0 (pure yellow), I would expect HSV 60° / 100% /
100%. Instead I'm getting 255 / 255 / 30. I did this for a few different colors and I
think the output is as follows: 
value as UINT8 between 0 and 255
saturation as UINT 8 between 0 and 255
0.5 * Hue as UINT8 between 0 and 180. 

The help doesn't explain any of this, i.e. which data types, which range, which order
the function expects as inputs and / or delivers as outputs. Could that please be recified
and also double-checked for all other color space conversions?

r= 255;
g = 255;
b = 0;

rgb(1,1,1)=r;
rgb(1,1,2)=g;
rgb(1,1,3)=b

hsv=rgb2hsv(uint8(rgb))
Answer from Yukiya Kawakami -- February 7, 2024, 09:17:30 AM    
Hi, Matthias Lehmann,

I think the causes are channel order handling.

Scilab-IPCV has the color order R-G-B.
But OpenCV has the color order B-G-R.
When Scilab uses OpenCV library,
API changes R-G-B of Scilab into B-G-R of OpenCV.
After OpenCV processing, the API changes B-G-R of 
OpenCV into R-G-B of Scilab.

In rgb2hsv.sci case, API also changes R-G-B unit8
image of Scilab into B-G-R CV_8U image of OpenCV.
After OpenCV processing, the API changes H-S-V 
CV_8U image of OpenCV into V-S-H uint8 image of
Scilab. So, V has range 0..255, S has range 
0..255, H has range 0..180.

This color order handling affects also rgb2lab.sci, 
rgb2ycbcr.sci and (hsv2rgb2.sci, ycbcr2rgb).

There is 2 ways to fix this inconvenient issue.

1. Write this color handling and this channel orders
   into help-browser for above macros(.sci).

2. Tweak/Edit above macros(.sci).

   /* For rgb2hsv.sci */
   /// from ///

   hsv=int_cvtcolor(rgb, 'rgb2hsv');

   /// to ///

   hsv=int_cvtcolor(rgb, 'rgb2hsv');
   hsv(:,:,1:3)=hsv(:,:,3:-1:1);

   // Though unit8 image, the color order is H-S-V
   /////////

   /* For hsv2rgb2.sci, if rgb2hsv.sci is edited as above. */
   /// from ///  

   rgb=int_cvtcolor(hsv, 'hsv2rgb');

   /// to ///

   hsv(:,:,1:3)=hsv(:,:,3:-1:1);
   rgb=int_cvtcolor(hsv, 'hsv2rgb');

   //////////

Also, rgb2lab.sci, rgb2ycbcr.sci and ycbcr2rgb.sci
will be edited like above.
Making lab2rgb.sci that doesn't exist now, is other issue.

I hope this helps a little.
Y. Kawakami
Leave a comment
You must register and log in before leaving a comment.
Login with GitLab
Email notifications
Send me email when this toolbox has changes, new files or a new release.
You must register and log in before setting up notifications.