Re: [Scilab-users] ?= creating ROI from mouse click
...so to better explain my purpose: Assumptions: - one has a 2D Array of data or a gray scale Image - one wants to select the Region of interest via mouse clicks, by clicking into the Image - the ROI can be of any shape (triangle, rectangle, parallelogram, 5-point star ...etc) - one wants to Display only the ROI...everything outside of the ROI should be set to 0 purpose of ROI - one wants to process only a part of the input Image in such a way that: -if Pixel belongs to ROI than process Image - if Pixel does not belong to ROI do nothing So since I somehow can't figure it out how to: - calculate by hand if a pixel is left, right, above or below a line defined by two points (to bad, i know) and therfore - sort pixels in such a way that they either belong to the ROI or not I use the mentioned approach. Here the code: function [ROI, ROIpoints]=RoiImage(img); cols = size(img,'c'); rows = size(img,'r'); f = figure(); ShowImage(im,'click with mouse into image');// use of IDP function, could be exchanged by Matplot() a = gca(); a.margins = [0 0 0 0]; messagebox(["left click into the image to get ROI borders";"end with any other button"], "Information", "info", ["OK"]) ibutton = 3; nr_points = 0; while ibutton == 3; [ibutton,xcoord,ycoord]=xclick(); if ibutton == 3 then nr_points = nr_points + 1 plot(xcoord, ycoord,'o'); ROIpoints(nr_points,:) = double([xcoord ycoord]); end end nr_points = max(size(ROIpoints)); if nr_points < 3 then mprintf('not enough points \n'); mprintf('ROI requires minimal 3 points \n'); ROI = 0; return; end; f = figure(); f.background = 8; f.axes_size = [cols,rows]; x=ROIpoints(:,1); y=ROIpoints(:,2); xfpolys(x,y,[-1]); // how does xfpolys know which area to fill? Is this area stored somewhere as a variable? a=gca(); a.tight_limits = "on"; a.data_bounds=[0,0;cols,rows]; a.margins = [0 0 0 0]; xs2bmp(gcf(),'mask.bmp'); maskIm = RGB2Gray(ReadImage('mask.bmp')); // uses IDP functions deletefile('mask.bmp'); ROI = zeros(rows,cols); pos = find(maskIm < 255); ROI(pos)= 1; delete(); endfunction -- There we have the salad. ___ users mailing list users@lists.scilab.org http://lists.scilab.org/mailman/listinfo/users
Re: [Scilab-users] ?= creating ROI from mouse click
Le 11/03/2016 10:45, Antoine Monmayrant a écrit : You may give a try to edit_curv() I will soon propose to upgrade it. Thanks for the info. In its current form, it is not possible to close the curve, is it? . Just initialize it with xy($+1,:) = xy(1,:), or do that after returning. By the way, edit_curv() is somewhat outdated, but can't yet be replaced/upgraded with the private useeditor(nFig) (yet faster for interactions), whose implementation is -- IMO -- quite far being completed. Missing features could be listed. Samuel ___ users mailing list users@lists.scilab.org http://lists.scilab.org/mailman/listinfo/users
Re: [Scilab-users] ?= creating ROI from mouse click
Hello, For selecting a ROI of any shape, after displaying the grayplot: * plot(x,y) at least a segment around the middle of the grayplot. Choose an appropriate line color. * run useditor(gcf().figure_id) * interact with the initial segment : o click on a link to insert a point o click on and drag a point to move it with its links to neighboors o double-click on a point to delete it * Doing that = define your area. Interactions are not "modal" = after running useeditor(), Scilab does not wait for it returning. And when the editor is quit (right-click + Exit), no signal is sent to the console, and AFAIK there is no way to read out the current status of this editor. * Then, gce().children.data returns the XY Nx2 matrix of coordinates of your curve. * You close it: XY($+1,:) = XY(1,:) This ends the selection part. After that, identifying points of your grayplot area being in the curve may be done with point_in_polygon: https://fileexchange.scilab.org/toolboxes/121000 However, this script is not vectorized. So, if your full area has big sizes, it may takes a while. I would not guaranty that point_in_polygon() can be vectorized, but we may try to. It does not look too bad, at first sight :) HTH Regards Samuel Le 11/03/2016 11:01, Philipp Mühlmann a écrit : ...so to better explain my purpose: Assumptions: - one has a 2D Array of data or a gray scale Image - one wants to select the Region of interest via mouse clicks, by clicking into the Image - the ROI can be of any shape (triangle, rectangle, parallelogram, 5-point star ...etc) - one wants to Display only the ROI...everything outside of the ROI should be set to 0 purpose of ROI - one wants to process only a part of the input Image in such a way that: -if Pixel belongs to ROI than process Image - if Pixel does not belong to ROI do nothing So since I somehow can't figure it out how to: - calculate by hand if a pixel is left, right, above or below a line defined by two points (to bad, i know) and therfore - sort pixels in such a way that they either belong to the ROI or not I use the mentioned approach. Here the code: function [ROI, ROIpoints]=RoiImage(img); cols = size(img,'c'); rows = size(img,'r'); f = figure(); ShowImage(im,'click with mouse into image'); // use of IDP function, could be exchanged by Matplot() a = gca(); a.margins = [0 0 0 0]; messagebox(["left click into the image to get ROI borders";"end with any other button"], "Information", "info", ["OK"]) ibutton = 3; nr_points = 0; while ibutton == 3; [ibutton,xcoord,ycoord]=xclick(); if ibutton == 3 then nr_points = nr_points + 1 plot(xcoord, ycoord,'o'); ROIpoints(nr_points,:) = double([xcoord ycoord]); end end nr_points = max(size(ROIpoints)); if nr_points < 3 then mprintf('not enough points \n'); mprintf('ROI requires minimal 3 points \n'); ROI = 0; return; end; f = figure(); f.background = 8; f.axes_size = [cols,rows]; x=ROIpoints(:,1); y=ROIpoints(:,2); xfpolys(x,y,[-1]); // how does xfpolys know which area to fill? Is this area stored somewhere as a variable? a=gca(); a.tight_limits = "on"; a.data_bounds=[0,0;cols,rows]; a.margins = [0 0 0 0]; xs2bmp(gcf(),'mask.bmp'); maskIm = RGB2Gray(ReadImage('mask.bmp'));// uses IDP functions deletefile('mask.bmp'); ROI = zeros(rows,cols); pos = find(maskIm < 255); ROI(pos)= 1; delete(); endfunction -- There we have the salad. ___ users mailing list users@lists.scilab.org http://lists.scilab.org/mailman/listinfo/users ___ users mailing list users@lists.scilab.org http://lists.scilab.org/mailman/listinfo/users
Re: [Scilab-users] ?= creating ROI from mouse click
Le 12/03/2016 00:42, Samuel Gougeon a écrit : * run useditor(gcf().figure_id) . Sorry, please read: useeditor(gcf().figure_id) It is not documented. So right spelling matters. ___ users mailing list users@lists.scilab.org http://lists.scilab.org/mailman/listinfo/users
Re: [Scilab-users] ?= creating ROI from mouse click
Le 12/03/2016 00:42, Samuel Gougeon a écrit : .../... This ends the selection part. After that, identifying points of your grayplot area being in the curve may be done with point_in_polygon: https://fileexchange.scilab.org/toolboxes/121000 However, this script is not vectorized. So, if your full area has big sizes, it may takes a while. I would not guaranty that point_in_polygon() can be vectorized, but we may try to. It does not look too bad, at first sight :) . Actually, its vectorization is straightforward (to process a matrix of points without explicit "for" loop, instead of a unique point). But the script has other problems. Special cases (horizontal segments, points on segments, etc) are not really handled. Nevertheless, you may give it a try as is. Or improve it for special cases. Samuel ___ users mailing list users@lists.scilab.org http://lists.scilab.org/mailman/listinfo/users
Re: [Scilab-users] ?= creating ROI from mouse click
@ Samuel, thanks for the link. This is a nice function and it is doing what I am searching for. My example is rather slow though and I don't think that it is handy if one deals with big 2D Arrays. For a 640 x 512 array it took me 55 seconds to get the mask. guess the two for loops are the reason. clc;tic() img = rand(512,614).*255; rows = size(img,'r');cols = size(img,'c'); mask = zeros(img);xpol = [];ypol = [];ibutton = 3;nr_points = 0; f=figure();f.color_map=graycolormap(255);Matplot(img); while ibutton == 3; [ibutton,xcoord,ycoord]=xclick(); if ibutton ==3 nr_points = nr_points + 1; plot(xcoord,ycoord,'o'); xpol(nr_points) = xcoord; ypol(nr_points) = rows-ycoord; end;enddelete(gcf()); for i = 1:rows; for j = 1:cols inside = point_in_polygon(xpol, ypol, j, i) ; if inside == %t; mask(i,j) = 1; end; endend f = figure();f.color_map=graycolormap(255);Matplot(img.*mask);plot(xpol,rows-ypol,'o'); t = toc()disp(t); 2016-03-12 1:02 GMT+01:00 Samuel Gougeon : > Le 12/03/2016 00:42, Samuel Gougeon a écrit : > > .../... > > This ends the selection part. > > After that, identifying points of your grayplot area being in the curve > may be done with > point_in_polygon: https://fileexchange.scilab.org/toolboxes/121000 > However, this script is not vectorized. So, if your full area has big > sizes, it may takes a while. > > I would not guaranty that point_in_polygon() can be vectorized, but we may > try to. > It does not look too bad, at first sight :) > > . > Actually, its vectorization is straightforward (to process a matrix of > points without explicit "for" loop, > instead of a unique point). But the script has other problems. > Special cases (horizontal segments, points on segments, etc) are not > really handled. > Nevertheless, you may give it a try as is. Or improve it for special cases. > > Samuel > > > ___ > users mailing list > users@lists.scilab.org > http://lists.scilab.org/mailman/listinfo/users > > -- There we have the salad. ___ users mailing list users@lists.scilab.org http://lists.scilab.org/mailman/listinfo/users
Re: [Scilab-users] ?= creating ROI from mouse click
to end this topic: many thanks to the authors of the Matlab / Octave compatiblity toolbox Their function moc_inpolygon is doing the same thing, but way faster. 2016-03-12 13:20 GMT+01:00 Philipp Mühlmann : > @ Samuel, > > thanks for the link. > > This is a nice function and it is doing what I am searching for. > > My example is rather slow though and I don't think that it is handy if one > deals with big 2D Arrays. > > For a 640 x 512 array it took me 55 seconds to get the mask. > > guess the two for loops are the reason. > > clc;tic() > img = rand(512,614).*255; > rows = size(img,'r');cols = size(img,'c'); > mask = zeros(img);xpol = [];ypol = [];ibutton = 3;nr_points = 0; > f=figure();f.color_map=graycolormap(255);Matplot(img); > while ibutton == 3; > [ibutton,xcoord,ycoord]=xclick(); > if ibutton ==3 > nr_points = nr_points + 1; > plot(xcoord,ycoord,'o'); > xpol(nr_points) = xcoord; > ypol(nr_points) = rows-ycoord; > end;enddelete(gcf()); > for i = 1:rows; > for j = 1:cols > inside = point_in_polygon(xpol, ypol, j, i) ; > if inside == %t; > mask(i,j) = 1; > end; > endend > f = > figure();f.color_map=graycolormap(255);Matplot(img.*mask);plot(xpol,rows-ypol,'o'); > t = toc()disp(t); > > > > > > > > > 2016-03-12 1:02 GMT+01:00 Samuel Gougeon : > >> Le 12/03/2016 00:42, Samuel Gougeon a écrit : >> >> .../... >> >> This ends the selection part. >> >> After that, identifying points of your grayplot area being in the curve >> may be done with >> point_in_polygon: https://fileexchange.scilab.org/toolboxes/121000 >> However, this script is not vectorized. So, if your full area has big >> sizes, it may takes a while. >> >> I would not guaranty that point_in_polygon() can be vectorized, but we >> may try to. >> It does not look too bad, at first sight :) >> >> . >> Actually, its vectorization is straightforward (to process a matrix of >> points without explicit "for" loop, >> instead of a unique point). But the script has other problems. >> Special cases (horizontal segments, points on segments, etc) are not >> really handled. >> Nevertheless, you may give it a try as is. Or improve it for special >> cases. >> >> Samuel >> >> >> ___ >> users mailing list >> users@lists.scilab.org >> http://lists.scilab.org/mailman/listinfo/users >> >> > > > -- > There we have the salad. > -- There we have the salad. ___ users mailing list users@lists.scilab.org http://lists.scilab.org/mailman/listinfo/users