Isolate low contrast rectangle of known size from image

4 views (last 30 days)
Hi all,
I am trying to isolate a low contrast rectangular shape from an image that already has a high variety of objects with different intensities. Normally, I would not expect typical identification algorithms to work since this rectangle is hard to numerically segment. However, I can afford to have "previous knowledge" of the rectangle's size (i.e. 30 x 340 pixels) which I thought might allow it to be isolated. I was thinking maybe create a mask of the expected size and interate through the image until the best match of uniform intensity is found, but I think this would create a lot of false positives. Is there any way to approach this issue and identify the location of the rectangle?
I included the sample image along with another image outlining where the rectangle in question is located.
Thank you!
  5 Comments
Roman
Roman on 27 Apr 2022
You are correct, the reconstruction results in easer identification. However, for my application I specifically need to analyze the projection data.
Matt J
Matt J on 28 Apr 2022
But if you locate the object in 3D, it would not be too hard to locate it in projection space through forward projection.

Sign in to comment.

Accepted Answer

DGM
DGM on 28 Apr 2022
Edited: DGM on 28 Apr 2022
This might be an idea for a way. With only one test case, it's hard to tell if this is even remotely robust. I imagine it can be broken fairly easily if any narrow high contrast features become aligned with the rectangle edges.
It's hard to verify the rectangle alignment exactly, but it appears close. This works by finding the mean difference of two nested quasi-annular samples around a given point. It may be more appropriate to use some other measure other than the mean for testing the location. It may be better to look at the fraction of the interior pixels which are darker than their exterior neighbors -- or it may be better to calculate some combined metric based on more than one measure.
A = imread('https://www.mathworks.com/matlabcentral/answers/uploaded_files/980885/image.png');
A = rgb2gray(A);
% supposed rectangle geometry
rsz = [340 30];
% process image and find peak
B = nlfilter(A,rsz+2,@rectfun);
[~,idx] = max(B(:));
[y x] = ind2sub(size(A),idx);
% the filtered image and estimated center
imshow(B,[]); hold on
plot(x,y,'yo')
% the image and estimated rectangle boundary
imshow(A); hold on
plot(x+rsz(2)*[1 -1 -1 1 1]/2,y+rsz(1)*[-1 -1 1 1 -1]/2)
function out = rectfun(thisblock)
outerannulus = [thisblock(1,3:end-2) thisblock(end,3:end-2) ...
thisblock(3:end-2,1).' thisblock(3:end-2,end).'];
innerannulus = [thisblock(3,3:end-2) thisblock(end-2,3:end-2) ...
thisblock(3:end-2,3).' thisblock(3:end-2,end-2).'];
out = mean(outerannulus-innerannulus);
end
In practice, this would likely be faster to write a simple 2-loop sliding window routine and get rid of nlfilter(), but this was just quicker to prototype the idea. It's probably going to be fairly slow either way.
  1 Comment
Roman
Roman on 6 May 2022
Thank you!!! This approach is very interesting and I think could work very well!

Sign in to comment.

More Answers (1)

Image Analyst
Image Analyst on 27 Apr 2022
Because it's such low contrast on a complicated, varying background, and it seems like it would require expert knowledge to define exactly where each of the 4 edges are, I'd just do it manually with drawrectangle(). See attached demo.
  4 Comments
Image Analyst
Image Analyst on 27 Apr 2022
If you have only a few images, your fastest route is to just manually locate the region.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!