Hough Transform Matlab - how to display? - matlab

I got a code from the book Feature Extraction & Image Processing.
As I am a total beginner in Matlab, I don't know how to run these codes to see results.
Are they complete?
First one : Hough Transform for Lines
%Polar Hough Transform for Lines
function HTPLine(inputimage)
%image size
[rows,columns]=size(inputimage);
%accumulator
rmax=round(sqrt(rows^2+columns^2));
acc=zeros(rmax,180);
%image
for x=1:columns
for y=1:rows
if(inputimage(y,x)==0)
for m=1:180
r=round(x*cos((m*pi)/180)+y*sin(m*pi)/180);
if(r0) acc(r,m)=acc(r,m)+1; end
end
end
end
end
Second one : Hough Transform for Circles
%Hough Transform for Circles
function HTCircle(inputimage,r)
%image size
[rows,columns]=size(inputimage);
%accumulator
acc=zeros(rows,columns);
%image
for x=1:columns
for y=1:rows
if(inputimage(y,x)==0)
for ang=0:360
t=(ang*pi)/180;
x0=round(x-r*cos(t));
y0=round(y-r*sin(t));
if(x00 & y00)
acc(y0,x0)=acc(y0,x0)+1;
end
end
end
end
end
Third one : Hough Transform for Elipses
%Hough Transform for Ellipses
function HTEllipse(inputimage,a,b)
%image size
[rows,columns]=size(inputimage);
%accumulator
acc=zeros(rows,columns);
%image
for x=1:columns
for y=1:rows
if(inputimage(y,x)==0)
for ang=0:360
t=(ang*pi)/180;
x0=round(x-a*cos(t));
y0=round(y-b*sin(t));
if(x00 & y0< rows & y0>0)
acc(y0,x0)=acc(y0,x0)+1;
end
end
end
end
end
I have images (png) that I need to run these programs with.
But I cannot seem to run it.
I create new script, paste the code, save it and in main window I run the function name sending path to the image as a parameter. It does nothing, no message or so.

Your functions don't return any value, that means that you have to add a return argument to those functions (in case of the hough trafo, you'd like to return the accumulator array acc) and as described in the manual (http://www.mathworks.de/de/help/matlab/ref/function.html), change the functions headers to:
function acc = HTPLine(inputimage)
and then also call it like this from the commandline (or from another script):
IMG = imread('some_image.jpg');
% e.g. convert to grayscale:
IMG = rgb2gray(IMG);
acc = HTPLine(IMG);
you then still need to find the maximum (or several maxima, depending on how many lines you'd like to fit) in the accumulator and display the fitted line (ellipse/circle) on your own via plot in a figure...
EDIT: Looking at your code, I don't know what the variable r0 should be!? It will def. give you an errormsesage as it's not defined anywhere.
And why do you the if(inputimage(y,x)==0) in your code? The pixel at the current point doesn't have to be black in ordner to calculate the hough transformation for that single pixel (just think of a grey-image with a white line in it -> your code wouldn't do anything as the image wouldn't contain any black pixels). So that's what you need to rethink about.
If you want to, you could also use the built-in hough transformation of MATLAB: http://www.mathworks.de/de/help/images/ref/hough.html // http://www.mathworks.de/de/help/images/ref/houghpeaks.html

Related

Active contour snake

I am trying using MATLAB activecontour code to segment the region. the example was used grayscale image while i am using binary image. it turn out ok when i run the code by calling the binary image. however, when i combined the code, nothing happen. it skips the iteration part, and generate the sama binary image. for your reference, below is my code.
%% snake
figure
x = imread('1.jpg');
threshold = 160;
I = rgb2gray(x);
I = Igray>threshold;
imshow (I);
I = imresize(I,.5);
imshow(I)
title('Original Image')
mask = zeros(size(I));
mask(25:end-25,25:end-25) = 1;
imshow(mask)
title('Initial Contour Location')
bw = activecontour(I,mask,1300);
imshow(bw)
title('Segmented Image, 300 Iterations')
no process happen starting from snake's code. it eventually only generate binary image. I hope someone could try run this and help me to find my mistake. Thank you in advance
Matlab's activecontour function uses the Chan–Vese (active contours without edges) method by default, like Cris said. The implementation "uses the Sparse-Field level-set method, similar to the method described in [3]", citing Whitaker, "A level-set approach to 3d reconstruction from range data". (Besides Chan–Vese, activecontour has an optional method arg that can be set to 'edge' to use an alternative "edge-based model" based on the (older) geodesic active contours method of Caselles, Kimmel, and Sapiro.)
The Chan–Vese method segments a grayscale image by looking for a binary image equal to "c1" inside the contour and "c2" outside the contour that both has a smooth contour and is a good approximation to the original image. The method optimizes c1, c2, and the shape of the contour, beginning from some initial contour and evolving it by an iterative process.
If you'll excuse a self-citation, you can find an article, open source C code, and online demo about Chan–Vese on the IPOL journal at http://www.ipol.im/pub/art/2012/g-cv/, which you may find helpful.
So why is it not working in your case? Some thoughts:
In your use, since the input image is already binary, it is clearly tempting for the method to simply set c1=0, c2=1, and the contour to the edges of the input, so "nothing happens". Try setting the optional 'SmoothFactor' arg (possibly to a large value) to force the method to look for a smoother contour.
It's conceivably a datatype problem, since image I is passed as a logical array to activecontour, but normally the function takes a numeric array. Try casting I to a double array before passing.

Detect parallel lines using Hough transform in matlab

Suppose there is a binary image of a black background and white lines "plotted" on it, i.e., they aren't burnt onto the image. For example:
I need to retain only the lines that are parallel to atleast one of the other lines in the picture. If not perfectly parallel, at least close enough to be parallel(perhaps a variable that can control the degree of parallelism would help with that). In other words, if I choose a particular line and it has one or more lines that are parallel to it, I retain it, else I discard it. I need to do that for all lines in the image.
I came across Hough transform but I'm having trouble understanding how to use the bins to check the orientations and determine parallel lines. Or is there a better way to go about this?
Also, since the lines aren't a part of the image and are just plotted on it, I don't have an image to feed into the Hough Transform function. Can I use the output of the plot function as input directly? This is the code I wrote to plot the white lines:
Location1 is a m-by-2 matrix that contains the coordinates to draw the lines.
figure; imshow(blackImage);
hold on ;
for i=1:size(Location1,1)-1
h = plot([Location1(i,1) Location1(i+1,1)], [Location1(i,2) Location1(i+1,2)]) ;
set(h,'linewidth', .1, 'color', 'b') ;
end
Any help would be appreciated.
Given that
for i=1:size(Location1,1)-1
% one line = Location1(i,:) to Location1(i+1,:)
end
then
theta = atan2(diff(Location1(:,2)),diff(Location1(:,1)));
But since lines are parallel even if their theta is in the opposite direction, you want to map all angles to half a circle:
theta = mod(theta,pi/2);
Now theta is in the range [-π/2,π/2].
To find similar angles:
[s,i] = sort(theta);
k = find(diff(s)<0.01); % diff(s) is always positive because s is sorted
i = i([k,k+1]);
theta(i) % <-- sets of similar angles
% Location1(i,:),Location1(i+1,:) <- corresponding lines

how can i apply exact dct2 on 8x8 blocks and display them in subplots?

I=imread('ft.jpg');
[a b]=size(I);
figure;imshow(I);
j=rgb2ycbcr(I);
[m n]=size(j);
figure;
imshow(j);
ca=mat2cell(j,8*ones(1,size(j,1)/8),8*ones(1,size(j,2)/8),3);
p = 1;
figure;
figure;
X=ones(m,n,8,8);
for c=1:size(ca,1)
for r=1:size(ca,2)
temp=zeros(8,8,'uint8');
temp(:,:)=X(c,r,:,:);
temp=temp-128;
temp=dct2(temp);
subplot(size(ca,1),size(ca,2),temp(:,:)); %// Change
imshow(ca{c,r});
p=p+1;
end
end
the error is:
Error using ==> subplot at 309
Illegal plot number.
Error in ==> project at 22
subplot(size(ca,1),size(ca,2),temp(:,:)); %// Change
That's because you're not calling subplot properly. It needs p as the parameter for the third argument, not temp. p determines which slot you want to place your figure in. You putting in a doublevector as the third parameter makes no sense. Also, ca contains 8 x 8 pixel blocks, and you'd like to show the DCT of each block. Your current code does not do this. Actually, X is what you're trying to find the DCT of, and it's all ones.... doesn't make much sense.
You probably want to show the DCT of each block inside the figure as well, not ca.... and so you need to do this:
for c=1:size(ca,1)
for r=1:size(ca,2)
temp = double(ca{c,r}); %// Change - cast to double for precision
temp=temp-128;
temp=dct2(temp);
subplot(size(ca,1),size(ca,2),p); %// Change
imshow(temp,[]); %// Change here too
p=p+1;
end
end
Note that I did imshow(temp,[]); so that we can contrast stretch the block so that the minimum value gets mapped to black while the maximum value gets mapped to white. Everything else is a shade of gray in between. Be advised that this doesn't change the image itself. It only changes it for display.
Suggestion
You should read up on my post on how subplot works here: How does subplot work and what is the difference between subplot(121) and subplot(1,2,1) in MATLAB?
Once you read through this post, you'll have a better understanding of how each parameter works for subplot, and how you can display graphs / images in a figure.
Minor Note
Looks like you took that code from this post but you didn't copy and paste properly :) That %// Change comment, as well as the variable name ca looked oddly familiar.

Extract Individual Line Segment Coordinates from Boundary Image - MATLAB

I have a MATLAB script that gives me the boundary lines of an image using bwboundaries().
Now, after plotting that image, I am getting the complete image, formed from various straight line segments.
I would like to get the coordinates or show the individual line segments that form the boundary.
I think the method is called digital straightness of lines, but I want to know how to apply it here in this case.
[B,L,N] = bwboundaries(z,'noholes');
for k=1:length(B),
boundary = B{k};
if(k > N)
figure, plot(boundary(:,2),boundary(:,1),'g','LineWidth',2);
else
figure, plot(boundary(:,2),boundary(:,1),'r','LineWidth',2);
end
end
According to my understanding of your question,my idea is to use bwtraceboundary().
BW = imread('image.png');
imshow(BW,[]);
r = 165; % you can get the r and c for your image using "impixelinfo"
c = 43;
contour = bwtraceboundary(BW,[r c],'W',4,Inf,'counterclockwise');
hold on;
plot(contour(:,2),contour(:,1),'g','LineWidth',2);
x=contour(:,2)'
y=contour(:,2)'
Am I answering your question?
Use regionprops('desired feature') on the labelled image.
To generate a labelled image use
bwlabel(Img) (high memory usage)
or
bw=bwconncomp(Img,conn) (low memory use)
followed by
labelmatrix(bw)
The best way to proceed would probably be to use a Hough Transform to first get an idea of the lines present in the image. You can play around with Hough Transform to extract the end points of the lines.

Extracting Ring/Sector area from array representing an image

I am trying to extract features from an array representation of an image in MATLAB.
The features have a shape of a circle (ring) and a sector. This is shown in the image below. I have spent quite some time looking for a built-in function which does this. I have managed to do the ring extraction using an ugly looking loop but no idea where to start on the sector part. Any ideas how to implement this or even better a built-in function in MATLAB would be very helpful.
That's pretty easy, with no for loops needed, see for example in case your image is im:
[x y]=meshgrid(1:size(im,1));
f =#(x0,y0,r_max,r_min,theta1,theta2) ...
(x-x0).^2+(y-y0).^2<=r_max^2 & ...
(x-x0).^2+(y-y0).^2>=r_min^2 & ...
atan2(y-y0,x-x0)>=theta1 & ...
atan2(y-y0,x-x0)<=theta2;
f is a one liner anonymous function that accepts all needed parameters and gives a mask of the sector needed. For a ring you can set theta to be -pi to pi, or just delete the atan part from f. For example
r_max=40;
r_min=10;
x0=round(size(im,1)/2); %image center
y0=round(size(im,1)/2); %image center
theta1=deg2rad(10);
theta2=deg2rad(70);
imagesc(f(x0,y0,r_max,r_min,theta1,theta2))
set(gca,'YDir','normal')
axis square