How to fill empty parts of a projected image? - matlab

When i projected a 3D model on a 2D plan (Perspective projection) the result of the projection appeared as the following image.
and i need to fill empty points in this image to look like this one
i wonder that i can find a good way to fill this points with a professional way using any image processing algorithms using matlab

Code in Mathematica. Matlab surely has the equivalent image transformations.
Let's see how both images fit:
As you can see, the neck is a bit Hulkish ... otherwise the result is quite good

Here is a MATLAB version somewhat equivalent to #belisarius answer:
I = double(imread('http://i.stack.imgur.com/sedZH.png'));
BW = im2bw(I,graythresh(I));
BW = imerode(BW,strel('square',2*3+1));
BW = imfilter(BW, fspecial('average',10));
BW = imdilate(BW,strel('square',2*3+1));
BW = imcomplement(BW);
imshow(BW)

Related

Template matching

I am trying to detect elevators on floor plans in MATLAB. The code I have now is not detecting elevators, it is instead just pointing at the edges of the image. I am expecting to detect all the elevators on a floor plan. Elevators are represented by a square or rectangle with an x inside, similar to the template image. I have attached the template, image and a result screenshot.
Template image:
Image:
Results:
Code:
template= rgb2gray(imread('ele7.png'));
image = rgb2gray(imread('floorplan.jpg'));
%imshowpair(image,template,'montage')
c = normxcorr2(template,image);% perform cross-correlation
figure, surf(c), shading flat
[ypeak, xpeak] = find(c==max(c(:)));%peak of correlation
%Compute translation from max location in correlation matrix, =padding
yoffSet = ypeak-size(template,1);
xoffSet = xpeak-size(template,2);
%Display matched area
figure
hAx = axes;
imshow(image,'Parent', hAx);
imrect(hAx, [xoffSet+1, yoffSet+1, size(template,2), size(template,1)]);
To check if everything runs smoothly, you should plot the correlation:
figure, surf(c)
As mention by #cris-luengo , it's easy to fail with the sizes of the image and so on. However, I've seen that you followed the tutorial on https://es.mathworks.com/help/images/ref/normxcorr2.html . Since both images, already black and white images (or 2-colour images), normxcorr2 works well with rgb images (with textures and objects, etc...). Thus, I think that is not a correct approach to use normxcorr2.
An approach I would consider is look for branches. Using Matlab's help and bwmorph:
BW = imread('circles.png');
imshow(BW);
BW1 = bwmorph(BW,'skel',Inf);
You first skeletonize the image, then you can use any of the functions that displayed on bwmorph's help (https://es.mathworks.com/help/images/ref/bwmorph.html). In this case, I'd search for branch points, i.e. crosslinks. It is as simple as:
BW2 = bwmorph(BW1,'branchpoints');
branchPointsPixels = find(BW2 == 1);
The indices of the branch points pixels, will be where it finds an X. However, it can be any rotated X (or +, ...). So you'll find more points that you desire, you would need to filter the points in order to get what you want.

how to remove the edge of an image after edge extraction using MATLAB?

I have an image in gray scale and I would like to remove the edge that is extracted by using an edge extraction method in MATLAB.
Is it possible to do it?
Below is my code that perform the edge extraction :
%load the image
A=imread('MikuBW.jpg');
%predefined edge extraction method in MATLAB
g=edge(A,'canny');
%plot results
subplot(2,1,1);
imshow(A),title('ORIGINAL');
subplot(2,1,2);
imshow(g),title('CANNY');
!(http://i.imgur.com/uS2Xxwf.jpg) [the result of original image and after edge extraction][1]
how do I remove the edge that is extracted in "CANNY" from the original image?
thank you for any help possible! =)
if you just want the "Canny" part to be removed, i.e. to be replaced with zeros, you can simply write:
A(g) = 0;
however, a more "natural" approach will be to blur the image, so it will have less edges in the first place:
H = fspecial('disk',5);
A = imfilter(A,H,'replicate');

Matlab: Using the warp function to map an image onto a sphere [duplicate]

So lets say I have black & white image that is read with imread() command and saved into matrix A.
I want to output/graph this matrix A image in a cylinder shape. I know how to draw a cylinder in MATLAB, but I do not have a clue what I should do if I want to put image on a cylinder or draw image in cylinder shape. Any help will be appreciated. Thank you.
I found this site from googling.
http://www.flashandmath.com/advanced/rolls/cylin.html
This is exactly what I want to do, but I need to do this in MATLAB.
The technique is called texture mapping. This is a code example from surface function (R2011b):
load clown
surface(peaks,flipud(X),...
'FaceColor','texturemap',...
'EdgeColor','none',...
'CDataMapping','direct')
colormap(map)
view(-35,45)
This example loads RGB image from "peppers.png" and maps it onto cylinder:
imgRGB = imread('peppers.png');
[imgInd,map] = rgb2ind(imgRGB,256);
[imgIndRows,imgIndCols] = size(imgInd);
[X,Y,Z] = cylinder(imgIndRows,imgIndCols);
surface(X,Y,Z,flipud(imgInd),...
'FaceColor','texturemap',...
'EdgeColor','none',...
'CDataMapping','direct')
colormap(map)
view(-35,45)
Things are even simpler with the warp function (comes with Image Processing toolbox) as natan suggested:
imgRGB = imread('peppers.png');
[imgRows,imgCols,imgPlanes] = size(imgRGB);
[X,Y,Z] = cylinder(imgRows,imgCols);
warp(X,Y,Z,imgRGB);

Finding notes in an image

I have an image like this. And I want to find the location of notes. What is the best way to find them ? (They are not circle and they are so small so circlefinder can't find them !)
Image of Notes !
Here is a bit of code to get you going...that's not perfect but it was a lof of fun haha.
What I did is to erode the image with a disk structuring element until what was left in the image was shapes the looked the most like circles. Then I eroded again but this time with a line structuring element oriented at an angle close to that of the notes; I figured it's about 15 degrees.
After that, call regionprops to get the centroids, and then plot them.
Code:
clear
clc
BW = im2bw(imread('Notes.png'));
BW = imclearborder(BW);
%//Erode the image with a disk structuring element to obtain circleish
%// shapes.
se = strel('disk',2);
erodedBW = imerode(BW,se);
Here erodedBW looks like this:
%// Erode again with a line oriented at 15 degrees (to ~ match orientation of major axis of notes...very approximate haha)
se2 = strel('line',5,15);
erodedBW2 = imerode(erodedBW,se2);
erodedBW2 looks like this:
Then find centroids and plot them
S = regionprops(erodedBW2,'Centroid');
figure;
imshow(BW)
hold on
for k = 1:numel(S)
scatter(S(k).Centroid(:,1), S(k).Centroid(:,2),60,'filled')
end
Output:
Empty notes are not detected but that's manageable using other morphological operations I guess.
Hope that helps!

Aligning an Image for OCR

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: