Point of intersection of circle and binary image MATLAB - matlab

I have skeletonize binary image and the junction information. I want to draw circle at junction points as center and want to find the point of intersection of circle and binary image.
I have written the following code:
BW = imread('circles.png');
imshow(BW);
BW2 = bwmorph(BW,'remove');
figure, imshow(BW2)
BW3 = bwmorph(BW,'skel',Inf);
figure, imshow(BW3)
BW3t = bwmorph(BW3,'thin');
figure, imshow(BW3t)
[rj, cj, re, ce] = findendsjunctions(BW3t, 1);
hold on
plot(cj(1),rj(1),'ob')
hold on
circle([cj(1),rj(1)],4,50,':r');
findendsjunctions.m and dependent file show.m can downloaded from here: http://www.csse.uwa.edu.au/~pk/research/matlabfns/LineSegments/findendsjunctions.m and here http://www.csse.uwa.edu.au/~pk/research/matlabfns/Misc/show.m respectively.
And circle.m can be downloaded from here: http://www.mathworks.co.uk/matlabcentral/fileexchange/2876-draw-a-circle/content/circle.m
I want to find whether circle intersect 2, 3 or 4 vessels around it (marked as star in an image). Even if circle transverse many times a single vessel but output should be one intersection point per vessel.
Please suggest how can I find the intersection of circle and binary vessels.
Thanks

I have found the point of intersection of circle and Binary image and the coordinates of 3 points (marked as star in an image provided with my question). I have change the function circle.m (mentioned in my question above ) to give output of all X and Y coordinates of circumference of the circle and then I have written the following matlab code:
[H, X, Y]=circle([cj(1),rj(1)],4,50,':r');
c = improfile(BW3t,X,Y)
x=1:length(c)
figure
plot(x, c,'r')
[maxtab, mintab]=peakdet(c, 1)
[pks,locs] = findpeaks(c)
pt1=[X(locs(1)) Y(locs(1))]
pt2=[X(locs(2)) Y(locs(2))]
pt3=[X(locs(3)) Y(locs(3))]
hold on
plot(pt1(1),pt1(2),'om','LineWidth',2)
hold on
plot(pt2(1),pt2(2),'og','LineWidth',2)
hold on
plot(pt3(1),pt3(2),'ob','LineWidth',2)
pt1, pt2 pt3 are three points where circle cuts the binary image

Related

How can I draw the rectangle including the surfPoints object on the image?

I have a grayscale image I want to extract the regions of interest using detectSURFFeatures(). Using this function I get a surfPoints object.
by displaying this object on the image I get circles as regions of interest.
For my case I want the rectangular areas encompassing these circles.
To be more clear i have a image 1:
I want to extract Region of Interest (ROI) using : detectSURFFeatures(), we obtain the image
if you can see we have circular region, and for my case i want the rectangular ROI that contains the circular region :
It looks like the radius is fully determined by the points.Scale parameter.
% Detection of the SURF features:
I = imread('cameraman.tif');
points = detectSURFFeatures(I);
imshow(I); hold on;
% Select and plot the 10 strongest features
p = points.selectStrongest(10)
plot(p);
% Here we add the bounding box around the circle.
c = 6; % Correction factor for the radius
for ii = 1:10
x = p.Location(ii,1); % x coordinate of the circle's center
y = p.Location(ii,2); % y coordinate of the circle's center
r = p.Scale(ii); % Scale parameter
rectangle('Position',[x-r*c y-r*c 2*r*c 2*r*c],'EdgeColor','r')
end
And we obtain the following result:
In this example the correction factor for the radius is 6. I guess that this value correspond to half of the default Scale propertie's value of a SURFPoints object (which is 12.0). But since there is no information about that in the documentation, I can be wrong. And be carreful, the scale parameter of each ROI is not the same thing as the scale propertie of a SURFPoints object.

Compute binary line thickness in normal direction

I would like to kindly ask you for the help with the definition of the line thickness. I have the binary curve. I need to find out a distance of each point of the curve skeleton to line edge in the direction of the normal. So, I firstly computed skeleton of the binary curve. Consequently, for each pixel of the skeleton I computed normal. This situation is depicted on the figure, showing the skeleton and a map of normal vectors from each pixel. In this point, I do not know how to compute the distance for each skeleton pixel to curve edge in the normal direction. Practically, I need to count number of the pixels (logical 1) from the skeleton pixels to the line edge in the normal direction. It means I need to obtain the vector, containing distance for each skeleton point. I would like to thank you in advance for your help.
Code for generating skeleton with normals:
clc;clear all;close all
i=rgb2gray(imread('Bin_Lines.bmp'));
BW=bwskel(logical(i));
% BW = image sceleton
Orientations = skeletonOrientation(BW,5); %5x5 box
Onormal = Orientations+90; %easier to view normals
Onr = sind(Onormal); %vv
Onc = cosd(Onormal); %uu
[r,c] = find(BW); %row/cols
idx = find(BW); %Linear indices into Onr/Onc
figure()
imshow(BW,[]);
%Plotting normals of binary skeleton
hold on
quiver(c,r,-Onc(idx),Onr(idx));
Here is the link where I store source codes and binary line image:
https://www.dropbox.com/sh/j84ep3k1604hsza/AABm92TUBX6yIp29Gc0v_PHHa?dl=0
You can use distance transform to compute the distance of each interior pixel to the boundary. Matlab has bwdist to do that for you.
Then you can extract the information for the skeleton pixels.
img = rgb2gray(imread('Bin_Lines.bmp'));
bw = bwskel(img > 128);
dst = bwdist(img <= 128); % need opposite contrast
distance_of_skel_pixels_to_boundary = dst(bw)
The distance dst looks like:

Matlab - rotate a card [duplicate]

This question already has answers here:
How to straighten a tilted square shape in an image?
(2 answers)
Closed 5 years ago.
I have a cropped image of a card:
The card is a rectangle with rounded corners, is brightly colored, and sits on a relatively dark background.
It is, therefore, easy to differentiate between pixels belonging to the card and pixels belonging to the background.
I want to use MATLAB to rotate the card so its sides are vertical and horizontal (and not diagonal) and create an image of nothing but the straightened card.
I need this to work for any reasonable card angle (say +45 to -45 degrees of initial card rotation).
What would be the best way of doing this?
Thanks!
You can do this by finding the lines made by the edges of the card. The angle of rotation is then the angle between one of the lines and the horizontal (or vertical).
In MATLAB, you can use the Hough line detector to find lines in a binary image.
0. Read the input image
I downloaded your image and renamed it card.png.
A = imread('card.png');
We don't need color information, so convert to grayscale.
I = rgb2gray(A);
1. Detect edges in the image
A simple way is to use the Canny edge detector. Adjust the threshold to reject noise and weak edges.
BW = edge(I, 'canny', 0.5);
Display the detected edges.
figure
imshow(BW)
title('Canny edges')
2. Use the Hough line detector
First, you need to use the Hough transform on the black and white image, with the hough function. Adjust the resolution so that you detect all lines you need later.
[H,T,R] = hough(BW, 'RhoResolution', 2);
Second, find the strongest lines in the image by finding peaks in the Hough transform with houghpeaks.
P = houghpeaks(H, 100); % detect a maximum of 100 lines
Third, detect lines with houghlines.
lines = houghlines(BW, T, R, P);
Display the detected lines to make sure you find at least one along the edge of the card. The white border around the black background in your image makes detecting the right edges a bit more difficult.
figure
imshow(A)
hold on
for k = 1:length(lines)
xy = [lines(k).point1; lines(k).point2];
plot(xy(:,1), xy(:,2), 'LineWidth', 2, 'Color', 'red');
end
title('Detected lines')
3. Calculate the angle of rotation
lines(3) is the left vertical edge of the card. lines(3).point2 is the end of the line that is at the bottom. We want this point to stay where it is, but we want to vector along the line to be aligned with the vector v = [0 -1]'. (The origin is the top-left corner of the image, x is horizontal to the right and y is vertical down.)
lines(3)
ans =
struct with fields:
point1: [179 50]
point2: [86 455]
theta: 13
rho: 184
Simply calculate the angle between the vector u = lines(3).point1 - lines(3).point2 and the vertical vector v.
u = lines(3).point1 - lines(3).point2; % vector along the vertical left edge.
v = [0 -1]; % vector along the vertical, oriented up.
theta = acos( u*v' / (norm(u) * norm(v)) );
The angle is in radians.
4. Rotate
The imrotate function lets you rotate an image by specifying an angle in degrees. You could also use imwarp with a rotation transform.
B = imrotate(A, theta * 180 / pi);
Display the rotated image.
figure
imshow(B)
title('Rotated image')
Then you would have to crop it.

Quantifying pixels from a list of coordinates

I have a list of coordinates, which are generated from another program, and I have an image.
I'd like to load those coordinates (making circular regions of interest (ROIs) with a diameter of 3 pixels) onto my image, and extract the intensity of those pixels.
I can load/impose the coordinates on to the image by using;
imshow(file);
hold on
scatter(xCoords, yCoords, 'g')
But can not extract the intensity.
Can you guys point me in the right direction?
I am not sure what you mean by a circle with 3 pixels diameter since you are in a square grid (as mentioned by Ander Biguri). But you could use fspecial to create a disk filter and then normalize. Something like this:
r = 1.5; % for diameter = 3
h = fspecial('disk', r);
h = h/h(ceil(r),ceil(r));
You can use it as a mask to get the intensities at the given region of the image.
im = imread(file);
ROI = im(xCoord-1:xCoord+1; yCoord-1:yCoord+1);
I = ROI.*h;

How do i rotate my image and save data into a matrix?

I have an intensity image where i marked with the impoly function a region of interest. I have a code that gives me back the vertices of the smallest rectangle still containing my polygon.
The rectangle is most of the times not aligned with the axes. I would like to receive the data inside the rectangle into a matrix form.I have been trying to find out the angle between the largest side of the rectangle and the x axis and then to rotate the image so the rectangle will be aligned with the axes.I will really appreciate any help or new ideas on how to extract the values inside my rectangle into a matrix.
Here is part of my code:
filename = uigetfile; %get the file name
obj = VideoReader(filename);
nFrames=obj.NumberOfFrames;
thisfig = figure();
for k = 1 : nFrames
this_frame = read(obj, k);
thisax = axes('Parent', thisfig);
image(this_frame, 'Parent', thisax);
if k==nFrames
title(thisax, sprintf('Frame #%d', k));
end
if k==1
result=input('How many polygons would you like to draw? ');
for i=1:result
handle=impoly;
accepted_pos = wait(handle);
BW = createMask(handle);
sparse_image=sparse(BW);
[XX, YY] = find(sparse_image);
[rectx,recty]=minboundrect(XX,YY); %the function that returns the vertices of the rectangle
points=[rectx(1),rectx(2),rectx(3),rectx(4);recty(1),recty(2),recty(3),recty(4)]
distance1=((points(1,2)-points(1,1))^2+(points(2,2)-points(2,1))^2)^0.5;
distance2=((points(1,3)-points(1,2))^2+(points(2,3)-points(2,2))^2)^0.5;
if(distance1>distance2) %which side of the rectangle is the largest
vector=[points(1,2)-points(1,1),points(2,2)-points(2,1)];
else
vector=[points(1,3)-points(1,2),points(2,3)-points(2,2)];
end
angleInDegrees = atan2(vector(2), vector(1)) * 180 / pi; %supposed angle between the largest side and the x axis
end
end
To be clear: I get a video and split it into frames and i need to follow a certain area in all of the frames in the video. I'm dealing with a video but i split it into frames so i'm really dealing with images. The rectangle i get is slanted most of the times,i.e not aligned with the axes of my image.
Confusing question.
The code refers to videos, not images.
Is the question about rotating an image? Is the question about retrieving a sub-matrix from an image?
Is the posted code really relevant to the question?
What have you tried?
From the doc:
this_frame = read(obj, k);
video = read(obj) reads in all video frames from the file associated with obj. The read method returns a H-by-W-by-B-by-F matrix, video, where H is the image frame height, W is the image frame width, B is the number of bands in the image (for example, 3 for RGB), and F is the number of frames read.
It seems that you do have the coordinates:
[rectx,recty]=minboundrect(XX,YY);
So I'd say that the matrix you're looking for is
A = this_frame(rectx(1):rectx(2), recty(1):rectx(y), 1, 1); % Red band
Please edit your question for clarity.