简体   繁体   中英

Auto selecting square blob area from image : Computer Vision

要处理的图像 I am trying to develop auto calibration plugin, for which I need average pixel value value of centre blob in the image. As of now I am converting this image to binary, and able to identify different blobs in image.

But, I want that central blob getting identified some how. Maybe we can take help of surrounding 6 small blobs.

Original Image: https://drive.google.com/open?id=0B9kvfpiOcM1EWnhJeGtBZ3A4eTg

Matlab Code:

I = imread('BLOB.TIF');
Ibw = ~im2bw(I, 0.75);
Ifill = imfill(Ibw,'holes');
Iarea = bwareaopen(Ifill, 500);

stat = regionprops(Ifinal,'boundingbox');
imshow(I); hold on;
for cnt = 1 : numel(stat)
    bb = stat(cnt).BoundingBox;
    rectangle('position',bb,'edgecolor','r','linewidth',2);
end

Your results are very close. After you perform the conversion to binary, thresholding and performing an area opening, you get this image:

在此处输入图片说明

There are pixels along the borders of the pixels that are still around. You can use the imclearborder function to remove pixels that are touching the border. To be absolutely sure, use 8-connectedness so that it searches for pixels in all 8 directions. The default is to use 4-connectedness which is North, South, East and West only:

Iclear = imclearborder(Iarea, 8);

We now get this image:

在此处输入图片说明

We're almost done. You want the entire blob to be detected, not just the different parts of the blob. What I would recommend you do is fill all of the gaps by using a morphological closing operator. Use a structure element that is quite large to ensure that you fill in the gaps. Something like a square structure element of size 50 x 50 should work. Use imclose in conjunction with strel to specify the structure element:

se = strel('square', 50);
out = imclose(Iclear, se);

We now get:

在此处输入图片说明

We can now use the above image as a mask to mask out all of the image except for your blob of interest by multiplying the mask and image together. You can also use the mask to index into the image directly and setting the pixels not belonging to the mask equal to 0. Let's opt for the second option. First make a copy of the image, then do the indexing:

filt = I;
filt(~out) = 0;
imshow(filt);

We now get:

在此处输入图片说明

It's not perfect, but it's a good start. You may have to tweak the parameters a bit to get it better.

Good luck!

This is a very ill-posed problem. Both you and the other answer are making very specific assumptions on the nature of such images that you will take during the automated calibration. And since those are not explicitly defined, we are left with assuming whatever we deem reasonable.

My answer for example assumes that the most well-defined horizontal line in any such images you take will be on the object you placed there, either as a shadow on the top, or the line between the object background and the big square. It also assumes that the top line of the center big square will be the second longest continuous horizontal line you will find in the image (apart from the bottom border of the object, and the lower line of the big square). Finally I am assuming the perspective won't change too much.

Frequently use imagesc() after each step to understand what is happening, otherwise this answer would take 50 pages.

% Normalize Image
image = double(BLOB);
image = (image - min(image(:)))*255/(max(image(:))-min(image(:)));

% Find Strong Horizontal Lines
Gy = imfilter(image,[-1 0 1]','replicate');
HH = abs(Gy)>prctile(abs(Gy(:)),95);

% Find the 10 Largest Lines
CC = bwconncomp(HH);
LengthList=sort(cellfun(@length,CC.PixelIdxList)','descend');
Lines = bwareaopen(HH,LengthList(10));
CC2 = bwconncomp(Lines);

This is Lines:

Need Reputation to Put Images...


% Get Coordinates of Every Point in the 10 Largest Lines
[y x] = cellfun(@(X) ind2sub(size(Lines),X) ,CC2.PixelIdxList,'UniformOutput',false);

% Find Descriptive Parameters of Each Line
minx = cell2mat(cellfun(@min ,x,'UniformOutput',false))';
maxx = cell2mat(cellfun(@max ,x,'UniformOutput',false))';
miny = cell2mat(cellfun(@min ,y,'UniformOutput',false))';
maxy = cell2mat(cellfun(@max ,y,'UniformOutput',false))';
meanx = mean([minx maxx],2);

% Find the Horizontal Length of Each Line
LineLengths = maxx-minx;

% Find the Pair of 2 Second Largest Lines - The Top and Bottom Border of
% the Square
SecondLongestLineUpperBound = max(LineLengths)-0.2*max(LineLengths);
SecondLongestLineLowerBound = max(LineLengths)/3;
SquareBorderIndx = find(LineLengths>=SecondLongestLineLowerBound & LineLengths<=SecondLongestLineUpperBound);

% Make Sure First of the Pair is the Lower Line
[~,OrderedIndx] = sort(maxy(SquareBorderIndx));
SquareBorderIndx = SquareBorderIndx(OrderedIndx);

% Draw a Small Rectangle in the ROI and Get the ROI
DD =zeros(size(Lines));
DD(maxy(SquareBorderIndx(1)):miny(SquareBorderIndx(2)),meanx(SquareBorderIndx(1))-LineLengths(SquareBorderIndx(1))/5:meanx(SquareBorderIndx(2))+LineLengths(SquareBorderIndx(2))/5)=1;
ROI = double(BLOB).*DD;

This is the ROI:

Need Reputation to Put Images...


% Find Mean Intensity In the ROI
Result = mean(ROI(ROI(:)>0));

Result =

   4.3598e+04

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM