Subscribe Bookmark RSS Feed

Extract a predefined zone within an image

Samir7791

Occasional Contributor

Joined:

Feb 7, 2017

Dear Everybody,

I want to tow know if it is possible to extract with a script the pixels within the predefined circle of my image (see attached).

Thanks in advance for your help.

Krs,

SamirApr2.png

1 ACCEPTED SOLUTION

Accepted Solutions
Craige_Hales

Staff

Joined:

Mar 21, 2013

Solution

Take a look at the canny filter example in the scripting index. The parameters are on sliders and may be too touchy if your data varies in intensity, but for the example image I used

Slider Settings in Scripting Index exampleSlider Settings in Scripting Index example

To get this

Canny filter detects edgesCanny filter detects edges

The noise in the image was smoothed, a lot, by the top two sliders. The bottom two sliders were adjusted to values appropriate for these pixel intensities. The script is in the example; you might be able to automate your process if the pictures are similar enough. The output is a B&W or ones and zeros image. You could grab those pixels in a matrix for further processing.

You might also want to do some analysis of the pixel colors. Maybe clustering would give you a dark blue and darker blue pair of clusters. Maybe you could use the x-y coordinates of the dark blue clustered pixels. for example:

// load the test image
img = open("$desktop/large.png","png");
// grab the rgb data from the image
{r,g,b} = img<<getpixels("rgb");
// make a data table from the r,g,b matrices
dt = newtable("imgdata",
	newcolumn("r",numeric,setvalues(r)),
	newcolumn("g",numeric,setvalues(g)),
	newcolumn("b",numeric,setvalues(b))
);
// cluster the table. I got this script by saving it from
// an interactive run of the clustering platform
p = dt<<K Means Cluster(
	Y( :r, :g, :b ),
	{Number of Clusters( 3 ), Name( "K-Means Clustering" ), Go},
	SendToReport( Dispatch( {}, "Control Panel", OutlineBox, {Close( 1 )} ) )
);
// add a column beside the rgb cols
p<<saveClusters;
// turn the column of clusters into a 2D mat
mat = shape(dt:cluster<<getvalues,nrows(r),ncols(r));
// there are three clusters in "mat", fiddle with rgb...
newwindow("cluster",newimage("rgb",{mat==1,mat==2,mat==3}));

Clustering results turned into an imageClustering results turned into an image

It might make more sense to work with the XY coordinates of the clustered pixels to find the parameters you want.

 

 

 

Craige
6 REPLIES
Craige_Hales

Staff

Joined:

Mar 21, 2013

Yes. Get a matrix of the pixel values for the entire image, something like

image<<getpixels (check the scripting index, I'm away from my desk right now).

You can get the pixels as separate r,g,b channels or as a combined JMP color.

Next, you'll need a mask matrix of the same dimensions, with ones for the pixels to keep and zeros for the pixels to reject. You can use a paint program with white for one and black for zero. Load that image and get just one channel, red perhaps (r,g,b should all be the same for the black and white image), which will have the zero and one values.

Now decide what you want the result to be: just an unordered list of only the interesting pixels? Or a matrix the same size as before with the uninteresting values set to zero? 

imageMatrix[ Loc(mask) ] will give you the unordered pixels where mask had non-zero values.

imageMatrix :* mask will give you zero where the mask is zero, original values where the mask is one. ( :* is the element-wise multiply. * is matrix-algebra multiply...not what you want.)

 

This post might help. 

 

Craige
Samir7791

Occasional Contributor

Joined:

Feb 7, 2017

Dear Craige,

Thank you for the suggestion.

Unfortunately, the localisation of the circle inside the image may move from on photo to another (not standardized yet).

My question is if it possible de detect the contours of the circle in an automatics way.

Krs,

Samir 

Craige_Hales

Staff

Joined:

Mar 21, 2013

Solution

Take a look at the canny filter example in the scripting index. The parameters are on sliders and may be too touchy if your data varies in intensity, but for the example image I used

Slider Settings in Scripting Index exampleSlider Settings in Scripting Index example

To get this

Canny filter detects edgesCanny filter detects edges

The noise in the image was smoothed, a lot, by the top two sliders. The bottom two sliders were adjusted to values appropriate for these pixel intensities. The script is in the example; you might be able to automate your process if the pictures are similar enough. The output is a B&W or ones and zeros image. You could grab those pixels in a matrix for further processing.

You might also want to do some analysis of the pixel colors. Maybe clustering would give you a dark blue and darker blue pair of clusters. Maybe you could use the x-y coordinates of the dark blue clustered pixels. for example:

// load the test image
img = open("$desktop/large.png","png");
// grab the rgb data from the image
{r,g,b} = img<<getpixels("rgb");
// make a data table from the r,g,b matrices
dt = newtable("imgdata",
	newcolumn("r",numeric,setvalues(r)),
	newcolumn("g",numeric,setvalues(g)),
	newcolumn("b",numeric,setvalues(b))
);
// cluster the table. I got this script by saving it from
// an interactive run of the clustering platform
p = dt<<K Means Cluster(
	Y( :r, :g, :b ),
	{Number of Clusters( 3 ), Name( "K-Means Clustering" ), Go},
	SendToReport( Dispatch( {}, "Control Panel", OutlineBox, {Close( 1 )} ) )
);
// add a column beside the rgb cols
p<<saveClusters;
// turn the column of clusters into a 2D mat
mat = shape(dt:cluster<<getvalues,nrows(r),ncols(r));
// there are three clusters in "mat", fiddle with rgb...
newwindow("cluster",newimage("rgb",{mat==1,mat==2,mat==3}));

Clustering results turned into an imageClustering results turned into an image

It might make more sense to work with the XY coordinates of the clustered pixels to find the parameters you want.

 

 

 

Craige
Samir7791

Occasional Contributor

Joined:

Feb 7, 2017

Dear Craige,

The canny filter is really helpful.

I will try to automate the process.

The clustering is also very interesting but the result is less clear for some other photos.

Thanks a lot for your help,

Samir

Samir7791

Occasional Contributor

Joined:

Feb 7, 2017

Dear Craige,

we deployed the solution in an automated way but we still need to adapt manually the threshold parameters because photos are heterogeneous. do you think it is possible to automate this step?

Thanks a lot,

Samir

 

Craige_Hales

Staff

Joined:

Mar 21, 2013

Maybe. You might be able to create a model using statistics about the pixel values in the image to create the two threshold values the filter needs. You might want to smooth the picture before the canny filter (not inside the canny filter) so you can build the model with the smoothed pixels. (Edit: the internal canny filter blur is better because it keeps track of floating point data. An external blur will reduce the floating point data to integer pixels values 0..255 in the blurred image, and most of your pixels in the dark image are 0..10 or so.)

https://en.wikipedia.org/wiki/Canny_edge_detector describes how the canny filter works; the large threshold value (very small for your pictures) is where a line starts. Two adjacent pixels must be different by that much. The line is "followed" until it drops below the small threshold value (very, very small for your pictures). "The two threshold values are empirically determined and their definition will depend on the content of a given input image."-Wikipedia

Are colors important in these images? If not, you might want to reduce the image to gray scale. It will become a simpler problem, I think. You could make a distribution of the gray scale values...

What will you do with the line after you get it in an image? Is it just a visualization, or will you do more computations on that image? The clustering approach might still work well if you need a center of mass and radius.

Craige