Image segmentation based upon optical features [closed] - matlab

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I have an image with some texture in a region shown in the first image. I want to segment the image based upon this texture. For this I have extracted feature as shown with blue squares (second image). I want to extract the region bound to the rectangular distribution of the features (shown by red dotted line).
Image 1:
Image 2:
Can somebody help me by suggesting some methodology to pursue this problem. Thanks

This looks like it might fit the GraphCut image segmentation framework:
You want to find a binary assignment per-pixel (1 - this pixel belongs to the foreground, 0 - the pixel is part of the background). This assignment should include as many "texture locations" as possible in the foreground, while preserving "smooth boundaries" between foreground and background.
The smoothness requirement prevents your "ideal" assignment to be 1 for the blue dots and zero everywhere else.
Now, how to search for such a binary assignment using Matlab?
Assume you have img of size H-by-W, and you have detected the locations of the texture features and stored these location in a 2-by-n matrix locs.
Setting the per-element cost:
>> bgCost = zeros( H, W );
>> bgCost( [1 H] * (locs-1) + 1 ) = 1000; %// put 1000 penalty for assigning texture dot to foreground
>> fgCost = 10*ones( H, W ); %// assign some positive penalty for assigning non-texture location to FG - prevent an "all foreground" solution.
>> fgCost( [1 H] * (locs-1) + 1 ) = 0;
Optimization:
>> lambda = 5; %// set relative weight between smoothness term and "texture" term
>> gch = GraphCut('open', cat(3, fgCost,bgCost), lambda * [0 1;1 0],
>> [gch BW] = GraphCut('expand', gch ); %//optimization
>> gch = GraphCut('close', gch ); %//cleanup
You should get a nice binary mask in BW
>> figure;imshow( BW, [] );title('binary mask');
There are three parameters you can play with if you are not satisfied with the result BW:
the cost you assign to texture dots in the background (set to 1000 here).
the cost you assign to non-texture pixels in the foreground (set to 10 here).
the relative strength of the smoothness cost lambda.
Try and change these values and see how they influence the resulting mask.
I use this matlab wrapper for GraphCut optimization.

Related

How to evaluate the quality of interpolation? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
I am building a pyramid of images. First I take a big picture and build a smaller one even smaller, etc. I use interpolation to reduce the image. And I need to understand at what interpolation there will be less lost information between images. This is what I mean by interpolation quality.
I am looking at horizontal gradients. Please tell me how good this criterion is or if there is something better.
Blurred = imfilter(img, PSF);
Blurred = im2double(Blurred)
Blurred2 = imresize(Blurred, [300 300], "Method", "bicubic");
[x0,y0] = meshgrid(1:360,1:360);
[x, y] = meshgrid(1:1.2:360, 1:1.2:360);
Blurred3 = interp2(x0, y0, Blurred, x,y, "spline");
gradX = diff(Blurred,1,1);
gradY = diff(Blurred,1,2);
gradX2 = diff(Blurred2,1,1);
gradY2 = diff(Blurred2,1,2);
gradX3 = diff(Blurred3,1,1);
gradY3 = diff(Blurred3,1,2);
[h, cx]=imhist(gradX);
[h2, cx2]=imhist(gradX2);
[h3, cx3]=imhist(gradX3);
h=log10(h);
h2 = log10(h2);
h3 = log10(h3);
figure, plot(cx, h)
hold on
plot(cx2, h2);
plot(cx3, h3);
hold off
You're using the finite difference approximation to the derivative. The units in gradX are intensity units/pixel, with "pixel" the distance between pixels (which is assumed to be 1). When you rescale your image, you increase the pixel size, but in the derivative you're still assuming the distance between pixels is 1. Thus, the values in gradX2 are larger than those in gradX. You'd have to normalize by the image width to correct for this effect.
But still, after normalization, I don't see how this is a measure of quality of the interpolation. The right question would be: how well can I reconstruct Blurred from Blurred2? I'm assuming here that Blurred has been blurred just sufficiently to avoid aliasing when resampling the image.
I would apply a 2nd round of interpolation to Blurred2 to recover an image of the same size as Blurred, then compare the two images using MSE or similar error measure.

How to use Graph Cuts for segmenting objects in grayscale 2D images?

I need to extract out some unwanted objects from chest x-ray images using Shai Bagon's Matlab Wrapper for Graph Cuts suggested by #rayryeng in this post.
I've read the paper by Boykov and got some idea of how Graph Cuts work. I've also downloaded the Shai Bagon's Matlab Warpper for Graph Cuts and compiled the required mex files. To get started, I downloaded the simple example of image segmentation. But, I'm confused of how I could use
[gch ...] = GraphCut(mode, ...);
for segmenting the unwanted objects in grayscale 2D images.
Any help is appreciated as always. Thanks.
The very basics:
img = imread('http:%//i.stack.imgur.com/nntda.png'); %// read the image
img = img(:,:,1); %// use only one channel as it is a gray scale image
Observing that the object is mostly brighter than 110, while the rest of the lungs are darker than this value, you can define the per-pixel data term:
Dc(:,:,1) = img > 110; %// cost of 1-st label (bg): penalize pixels brighter than 110
Dc(:,:,2) = img < 110; %// cost of 2-nd label (fg): penalize pixels darker than 110
lambda = 11; %// relative weight of smoothness cost vs. data cost
Sc = [0 1; 1 0]; %// give 0 cost for bg-bg or fg-fg transitions, and 1 cost for fg-bg transitions
Perform the optimization using GraphCut wrapper:
gch = GraphCut( 'open', Dc, lambda * Sc ); %// define the graph
[gch L] = GraphCut('expand', gch ); %//optimize and get the labeling L
gch=GraphCut('close',gch); %// clean up the mess
What can you do next? (Apart from upvoting and accepting this extraordinary answer)
Use a more sophisticated data cost - use L1 or L2 "distance" from the 110-level threshold.
Use a "smoother" smoothness cost - make the smoothness cost dependent on image edges.
Use an 8-connected grid graph rather than the default 4-connected - this will reduce the "staircase"-ness shape of the segmentation boundary.
Use a better foreground/background model - make an appearance model based on image patches rather on single pixels.
I'll leave it to you to figure out more exciting ways to improve on this method...

Drawing a 2-D figure in Matlab [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Please If anyone can give a hint on drawing this in matlab
( I am not asking for the actual code but just a hint....)
Hard do give a hint, as it is just one line of code.
rectangle('Position',[1,2,5,6])
To actually see the rectangle you need to set the axes limits:
axis equal
xlim([0,8])
ylim([0,9])
Regarding your comment: have a look at this answer which gives a little introduction into the core graphics objects you're lookling for.
Core Graphics Objects
Core graphics objects include basic drawing primitives:
Line, text, and polygon shells (patch objects)
Specialized objects like surfaces, which are composed of a rectangular grid of vertices
Images
To draw an arbitrary figure you can use plot. For example, this draws a trapezoid:
x = [1 7 4 2 1]; %// x coordinates of vertices
y = [1 1 3 3 1]; %// y coordinates of vertices
plot(x,y); %// do the plotting
axis([0 8 0 4]) %// set axis limits
As you se, you specify the vertices and plot (in its default behaviour) joins them with straight lines. You need to specify the first vertex again as a last vertex to close the polygon.

How to avoid curved corners in rectangular patch element in matlab figure?

When I generate a set of rectangular patches in a matlab figure, some of the rectangle edges are rendered curved or clipped rather than sharp, which is unwanted. This depends on the scale, zooming into the image tends to eliminate the effect. I thought this might have to do with an aliasing/compression effect. Curiously, using rectangle the problem seems to go away.
Here is an example of the problem at intermediate magnification (other problems such as dashed borders which shouldn't be there are also evident):
The code is from an answer to another question:
H=Hadamard(48); %# now to row-double the matrix
A=(1+H)/2;
B=(1-H)/2;
C=[A; B]; %# the code below randomly permutes elements within the rows of the matrix
[nRows,nCols] = size(C);
[junk,idx] = sort(rand(nRows,nCols),2); %# convert column indices into linear indices
idx = (idx-1)*nRows + ndgrid(1:nRows,1:nCols); %# rearrange whatever matrix
E = C;
E(:) = E(idx);
[X Y] = find(logical(E));
xl = length(X);
yl = length(Y);
figure, hold on
for ii=1:xl
patch(X(ii) + [0 0 1 1],Y(ii) + [0.15 0.9 0.9 0.1],[1 1 1],'Edgecolor',[1 1 1])
end
axis([0 max(X)+1 0 max(Y)+1])
axis('square')
set(gca,'color',[0 0 0])
set(gca,'XTickLabel',[],'YTickLabel',[],'XTick',[],'YTick',[])
My questions are:
(1) Is it possible (and how) to get rid of the curved corners and other glitches of patch objects seen in the example shown, at low to intermediate degrees of magnification used to display the entire figure on screen.
(2) Most important is to be able to generate an image file (jpg, png, pdf...) which lacks the curved corners. All formats I looked into appear to conserve the unwanted effect. Answering 2 makes answering (1) essentially unimportant, and answering (1) presumably solves (2).
Edit
Since the problem goes away when rectangle is used, this appears to be a problem with the matlab rendering engine? Note: the example was generated with R14 but the OP of the question linked to had similar problems (matlab version unknown).
I went through the various lighting and edge representation options available for patch objects but no improvement was observed.
The question is a likely repeat, for instance a similar questions was asked here.
The answer appears to be to avoid explicit use of patch when drawing rectangles. Use either fill or just rectangle instead. The following ways of generating the figure provide nearly equivalent results, as far as I could tell:
load had.mat % <-- load the data containing the matrix of interest in array E
[X Y] = find(logical(E));
xl = length(X);
yl = length(Y);
figure, hold on
for ii=1:xl
rectangle('Position',[X(ii) Y(ii)+.2 1 0.8],'facecolor',[1 1 1],'edgecolor',[1 1 1])
% fill([X(ii) X(ii) X(ii)+1 X(ii)+1], [Y(ii)+0.2 Y(ii)+0.8 Y(ii)+0.8 Y(ii)+0.2],[1 1 1],'edgecolor',[1 1 1],'marker','.','markersize',1)
end
set(gca,'color',[0 0 0])
set(gca,'XTickLabel',[],'YTickLabel',[],'XTick',[],'YTick',[])
set(gcf,'Renderer','zbuffer')

Applying an algorithm to a specific region of an image [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I'm trying to apply an algorithm only to a specific region of an image. I tried imfreehand, but not able, at least for me, to do that using this function.
So, is there some way when running my code for the operations to be applied only to some specific region of an image in MATLAB?
Thanks.
Using a mask defined by any of the "imroi" functions - imfreehand and imellipse included, you can use roifilt2 to filter just the roi using a given filter or function.
First, define the area:
imshow(I); %display your image
h = imfreehand; % now pick the region
BW = createmask(h); %makes BW mask
Then, use roifilt2 in one of the following ways -
Define a filter and apply it:
H = fspecial('unsharp');
I2 = roifilt2(H,I,BW);`
Apply a given function to the roi:
I2 = roifilt2(I, BW, 'histeq');
Apply a given function to the roi, specifying parameters:
fh = #(I)(histeq(I,5)); %define function
I2 = roifilt2(I, BW, fh);
The last is equivalent to calling I2 = hist(I,5); but only works on the defined roi.
ETA:
If you want to call multiple functions on the roi, it may be easiest to define your own function, which takes an image input (and optionally, other parameters), applies the appropriate filters/functions to the image, and outputs a final image - you would then call "myfunc" in the same way as "histeq" above.
You can try roipoly.
There is an example on SO here.
Here's an example:
img = imread('peppers.jpg'); % loads the image we want to use
[BW,xi,yi] = roipoly(img); % create a polynomial surrounding region
BW = repmat(uint8(BW),[1,1,3]); % create mask
selIMG = img.*BW; % apply mask to retain roi and set all else to 0
imview(selIMG)
se=strel('disk',3);
erosion=imerode(selIMG,se);
result_image=imsubtract(selIMG,erosion);
imview(result_image)
Edit
On erode: as the matlab doc explains, imerode picks the lowest value from the surrounding pixels (imdilate does the opposite). This means that the original treatment in my answer is inadequate for imerode, it would be better to set pixels outside the selection to max on the colorscale, and I provide an example here on how to do this "manually":
img = imread('peppers.jpg'); % loads the image we want to use
[BW,xi,yi] = roipoly(img); % logical mask which contains pixels of interest
nBW = uint8(~BW); % inverse of logical mask to pick surrounding pixels
surroundingMaxedOut = repmat(255*nBW,[1,1,3]); % set surrounding pixels to max value
nBW = repmat(nBW,[1,1,3]); % make mask with 3 channels to pick surrounding pixels
BW = repmat(uint8(BW),[1,1,3]); % make mask with 3 channels to handle RGB
selIMG = img.*BW; % pick the image region of interest
selIMG = selIMG + surroundingMaxedOut; % final selection with surrounding pixels maxed out
imview(selIMG) % inspect the selection
se=strel('disk',3);
erosion=imerode(selIMG,se); % apply erosion
finalIMG = img.*nBW + BW.*erosion; % insert eroded selection into the original image
imview(finalIMG)
As other answers show, matlab has routines that handle these operations implicitly and are more efficient not least in terms of memory management, however this example provides you with more control so you can see what is happening.