Aligning an Image for OCR - matlab

I am trying to align an image as a preprocessing step for OCR.
The problem is that I wish to align regions in images that contain text without using a template of an aligned image.
My idea was to first extract the borders of the ROI:
Then, draw some rectangle with fitting proportions(haven't thought on a way to do it automaticlly yet), and try to estimate the geometric transformation between them by using imregcorr:
After that, apply the obtained transformation on the image itself:
As you can see, the final result is far from perfect.
So I wish to know if there is a better way to obtain the coordinates change between the border and the rectangle and apply it on the image.
There's also the possiblity that my approach is too naive, and the solution to this is completely different, so feel free to suggest other methods as you see fit.
Thanks.

Thanks dervish!
I don't really know much about openCV, as I still have to learn C++/python (soon I will, probably).
But I did manage to implement something similar in matlab, using a projective transformation:
m = [mx my]; % Red border corners
s=[sx sy]; % Fixed rectangle borders
BW = poly2mask(mx,my,168,290);
mask = uint8(repmat(BW,[1 1 3]));
TFORM = cp2tform(m,s, 'projective');
Iw = imtransform(I.*mask,TFORM);
[y,x] = find(im2bw(Iw,0));
imshow(Iw(min(y):max(y),min(x):max(x),:))
And here's the result:

Related

How can I find the boundary surface in this image

I am new to image processing. I want to find the surface between black and white pixels which separates them. Here is the link of image.
The size of image is (21,900,900)
https://drive.google.com/file/d/1zUWK0Fb_n6f1JZou5mrUJq0x3h2X8mBK/view?usp=sharing
I tried to use boundarymask command of MATLAB in one plane of image but I am getting noise and also it works for 2d image only. Please suggest me how to find boundary 3d surface here. Thank you.
This is the output image after applying boundarymask.
Your first step should be to get rid of your noise. Since you got some kind of salt and pepper noise you can to that using the median filter on a 2D-image with medfilt2() in matlab. After that you can use an edge ditector to find your edge pixels. The code for this could look like this. If you want the surface, you need to loop this, over the 3rd dimension of your 3D-image. The code will look like this:
for ii=1:16
I=imread('image.tif',ii);
I_bs=boundarymask(I);
I_filt=medfilt2(I_bs,[7 7]);
boundarysurface(:,:,ii)=edge(I_filt,'Canny');
end
The edge detector I used here is certainly overkill for this easy case, but was the easiest thing I could think of in short term. If performance is relevant let me know, and I will give you another approach.

Unite endpoints of edge with line

I'm trying to make an object recognition program using a k-NN classifier. I've got a bunch of images for the training part of the classifier and a bunch of images to recognize. Those images are in grayscale and there's an object (only its edge) per image. I need to calculate their center of mass so I use
img=im2bw(img)
and then regionprops(img,'centroid').
The problem is that some of those edges aren't closed so regionprops doesn't work then. I tried eroding the image (the edge is black, white background) but the endlines of those edges are too apart from eachother. I tried using bwmorph function to do so but still can't make it work.
Any ideas?
EDIT
I'm adding some images in case anyone wants to try:
Use morphological operation
Use a closing operation to make your structures filled.
1. As first step prepare your image data
im = imread('your image.jpg');
% Get first channel as gray scale information
im = im(:,:,1);
% Threshold it for simplicyty, you may work on grayscale too.
im1 = logical(im > 128);
2. Use a simple block shaped structuring element
The structuring element is defined by:
strel=ones(3,3);
You may use disk shaped elements or whatever gives the best result to you.
3. Apply structuring element a couple of times
Apply the strel a couple of times with an erosion operator to your original image to close your figure:
for i=1:20
im1 = imerode(im1,strel);
end
4. Dilate the image to get back to original shape
Next step is to dilate the image to get back to your original outer shape:
for i=1:20
im1 = imdilate(im1,strel);
end
Final result
The final result should be suitable to get a sufficiently precise center or gravity.

Running feature extraction on region within a boundary

The image below shows a cow where the boundary has been detected using a combination of thresholding and subtracting a background from a 3D depth image.
My goal is to perform feature extraction on the area INSDIE the boundary. I have read the other questions and have struggled to implement the steps refereed to in similar questions. I do not want to extract the area in the boundary, I simply want to use it for feature extraction.
Please could someone offer a solution that is perhaps simpler? For example, is there a way to give the extractSURFFeatures the boundary coordinates from which to work within?
Below is my boundary code which recieves my processed thresholded image (BW1).
figure(1);
imshow(ImageCell_int{i-269});
%title('Outlines, from bwboundaries()'); axis square;
hold on;
boundaries = bwboundaries(BW1);
numberOfBoundaries = size(boundaries);
for k = 1 : numberOfBoundaries
thisBoundary = boundaries{k};
plot(thisBoundary(:,2), thisBoundary(:,1), 'g', 'LineWidth', 2);
end
hold off;
I would be extremely grateful for any assistance on this.
Great, now I see the cow! :)
You cannot specify an irregularly-shaped region of interest for the detectSURFFeatures function. However, you can detect the features in the whole image, and then create a binary mask of the region of interest, and use it to exclude keypoints, which are outside it.
Edit: If your boundary is represented as a polygon, you can use roipoly function to create a binary mask from it.
Having said that, features that are outside your object's boundary can actually be useful, because they capture information about the shape of the object.
Also, what is your final goal? If you want to recognize individual cows, then local features may not be the best approach. You may do better with a global HOG descriptor (extractHOGFeatures) or with a color histogram, or both.
This answer was discovered on Matlab Central and completely solves the problem above for anyone struggling with a similar issue.
Start with a grey scale outline of the object of interest (BW1).
% Make the mask black and white
double(BW1);
BW2 = logical(BW1);
Next the mask is created and forced to be the same size as the normal image.
mask = cast(BW2, class(normalImage));
maskedImage = normalImage .* mask;
imshow(maskedImage);
Yields the following result:
It is now possible to perform feature extraction on the object of interest.

find edge in image

How can I detect the edges in an image without using method 'edge', with only using mathematical operations (matrix or Derived or div or any other)? Indeed, how can I rewrite the function edge by using the algorithm Canny or sobel or any other?
For example:
pink rectangle 256*256
black rectangle 127*127
Answer:Canny Tutorial
You state that you wish to use Canny, Sobel or another algorithm. These can both be used in edge. Try for example:
BW = edge(I,'canny');
where I is your image matrix. If you are interested in finding out how edge works, type
edit edge
into your command window. You will then get to see MATLAB's own implementation.
You may wish to reimplement edge from scratch, to gain a good understanding of how image processing algorithms work. If so, I would direct you towards the following sources:
The Canny wikipedia page
The Sobel wikipedia page
I personally found this book an excellent reference for getting to grips with the basics of things like filters and edge detectors.
For your specific example with the rectangles, it is quite possible to use edge to find the edges. The one trick you have to do is to convert the rgb image to a grayscale one, using rgb2gray. Try for example:
rgb_image = imread('iarLe.png');
gray_image = rgb2gray(rgb_image);
edge_image = edge(gray_image);
imshow(edge_image);

matlab: correct approach to add geometrical objects to image

please help with Matlab beginner challenge
i need to create an image with few geometrical objects (circles,
ellipses) and then to apply some projective transforms
my problem is that i cant understand how to actually "draw" on image
image is AFAIU generally defined as [X;Y;3] matrix,
functions as SCIRCLE1 can compute/return collection of points
representing circle, but the problem is that points are not discrete ,
coordinates are real numbers and not pixels
how can i recompute the scircle output to be valid in image
coordinates system ? i.e. how can i "pixelize" it?
thanks for your attention, i really missing some basic concept and
will appreciate your help
John
well, below is an answer i received on Matlab newsgroups
BOTTOM LINE-no built-in way in Matlab
======================================
'getframe' can be used to merge axes even though it is more commonly used to create movie frames.
MATLAB is really weak in this area. There are some primitive
functions for drawing into the overlay (such as rectangle() if you
want to draw a circle, and line() if you want to draw a line) but no
real way that I know of to draw right into the underlying image. So
you have to use "tricks" such as getframe and then apply logical
operations. And you have to be careful with that since I think when
it gives you the rasterized version of the overlay it might be the
size of the image on the screen, not the true original matrix size of
the underlying image (I'd have to recheck this).
full thread here : http://www.mathworks.com.au/matlabcentral/newsreader/view_thread/261232
I found this example which give you a easy way to put simple geometrical object onto pictures.
Read the input image.
I = imread('cameraman.tif');
Define the rectangle dimensions as [x y width height].
rectangle = int32([10 10 30 30]);
Draw the rectangle and display the result.
J = step(shapeInserter, I, rectangle);
imshow(J);
see this link
by the way..
I didn't get you point about points not being discrete and images being a matrix. The way I see it. It much the same. you could try to explain it more in depth ?
The insertShape function in the Computer Vision System Toolbox is what you need. It lets you draw rectangles, circles, and polygons into the image.
There is also insertText, insertMarker, and insertObjectAnnotation.