I print out a digital image(say Img) with a colored printer. I than take the picture of the printed image, so now I have a new digital image say newImg. How can I find the four vertices of the original image(Img) in this newImg.

I am right now using the 'Harris Corner Detector' after dilating the image(dilation helps avoid false corners). But this method is not working. It is giving me many corners along with the actual four vertices and sometimes it is not giving me the actual corners at all. The background not necessarily black. It can be white(mostly it will be white), it can be some text or any other color but the image is easily distinguishable from the background. Also the image(Img) inside the image(newImg) is no more a rectangle after the perspective distortion that takes place while taking pictures from a camera i.e. our ROI is not a rectangle.
PS: you can add a frame around the actual image(IMG) before printing it out, and can make use of this frame while detecting.

Answers (1)

How about just finding the centroid of a thresholded version of the image. Then find the perimeter with bwboundaries(). Then find the 4 coordinates that are furthest from the centroid. Should be pretty simple. Give it a try.

4 Comments

https://www.dropbox.com/s/gy4t4zkcqud9jn1/2013-06-27%2014.32.35.jpg ---- here is the link to the image I wrote this code for. Some part of it was copied from Image Segmentation Tutorial ("BlobsDemo") by Image Analyst.
if true
clear all
img1 = imread('C:\Users\Abhay\Documents\My Received Files\2013-06-27 14.32.35.jpg'); imshow(img1);
img1 = imresize(img1, .20);% reducing the size for faster processing
img1 = ycbcr2rgb(img1);
img1 = img1(:,:,1);
[level EM] = graythresh(img1);
BW = im2bw(img1, level); imshow(BW);
imagesc(BW);
title('Outlines, from bwboundaries()'); axis square;
hold on;
boundaries = bwboundaries(BW);
numberOfBoundaries = size(boundaries);
for k = 1 : numberOfBoundaries
thisBoundary = boundaries{k};
plot(thisBoundary(:,2), thisBoundary(:,1), 'g', 'LineWidth', 2);
end
hold off;
end
I am getting the following image---- https://www.dropbox.com/s/gu6og0jmqjoho6r/boundary.png
This is not the boundary(perimeter) I intend to find.
Also tell me this, the centroid will be of the whole image. But I want the centroid of only the ROI i.e. the original image, right?
Thanks
I can't see anything from dropbox.com due to company firewall restrictions - it's one of only a very few file sharing sites that are banned. Anyway, you want the centroid of only the image within the image. So if you have a tilted rectangle (the print) sitting on a black background paper, you'd determine the value of the brightest part of the background and do
binaryImage = grayImage > backgroundIntensity;
binaryImage = imfill(binaryImage, 'holes'); % Fill rectangle.
binaryImage = bwareaopen(binaryImage, 10000); % Remove small noise.
measurements = regionprops(binaryImage, 'Centroid');
centroid = measure
IA, the OP has uneven illumination on the background image, so the automatic thresholding is not evenly selecting just the inside rectangle.
I want to clarify 2 things: 1)The background not necessarily black. It can be white(mostly it will be white), it can be some text or any other color but the image is easily distinguishable from the background. 2)the image(Img) inside the image(newImg) is no more a rectangle after the perspective distortion that takes place while taking pictures from a camera i.e. our ROI is not a rectangle.
I am not able to properly select just the concerned quadrilateral.

Sign in to comment.

Categories

Find more on Image Processing and Computer Vision in Help Center and File Exchange

Asked:

on 1 Jul 2013

Community Treasure Hunt

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

Start Hunting!