Find overlap area of two images with matlab - matlab

I want to find the overlap area of the two images using matlab.

If your ultimate goal is to stitch a panorama, you might want to consider this code.
In any case, to get the overlap area, you need to register the images first (find out, HOW they overlap - or more mathematically speaking: Find the transformation from image 1 to image 2). To do so you need to find matching points in both images.
The code below does that for two images (inspired by this code, which uses older MATLAB functions).
%% >>>>>>> load images and calculate their transformation <<<<<<< %%
im1 = imread('1.png');
im2 = imread('2.png');
imshowpair(im1, im2, 'montage');
% calculate features on grayscale image
im1g = rgb2gray(im1);
im2g = rgb2gray(im2);
points1 = detectSURFFeatures(im1g);
[features1, points1] = extractFeatures(im1g, points1);
points2 = detectSURFFeatures(im2g);
[features2, points2] = extractFeatures(im2g, points2);
% Find correspondences between im1 and im2
indexPairs = matchFeatures(features1, features2, 'Unique', true);
matchedPoints1 = points1(indexPairs(:,1), :);
matchedPoints2 = points2(indexPairs(:,2), :);
% Identity transformation
transform_eye = projective2d(eye(3));
% Estimate the transformation between im1 and im2
% we use a 'similarity' transform (translation/rotation), which treats the
% images as rigid bodys. 'affine' / 'projective' transformations allow for
% warping the images itself (the overlap might not be a rectangle).
transform = estimateGeometricTransform(matchedPoints1, matchedPoints2,...
'similarity', 'Confidence', 99.9, 'MaxNumTrials', 2000);
%% >>>>>>> apply transformation to images <<<<<<< %%
% create a world coordinate system (RF) that has space to store
% the reference image (im1) and the transformed image (im2)
R2 = imref2d(size(im2));
[~, R2T]=imwarp(im2,R2,transform);
xLimits=[min(0.5,R2T.XWorldLimits(1)) max(size(im1,2), R2T.XWorldLimits(2))];
yLimits=[min(0.5,R2T.YWorldLimits(1)) max(size(im1,1), R2T.YWorldLimits(2))];
width = round(xLimits(2) - xLimits(1));
height = round(yLimits(2) - yLimits(1));
RF = imref2d([height width], xLimits, yLimits);
% transform both images with regard to the world coordinate system RF
im1t=imwarp(im1,transform_eye,'OutputView',RF); % im1 stays in place (identity transform)
im2t=imwarp(im2,transform,'OutputView',RF); % im2 is transformed
% visualize result
imOverlay = im1t/2 + im2t/2;
imshow(imOverlay);
%% >>>>>>> get the overlap area only <<<<<<< %%
% if you only want the overlap area, apply the transform to image masks
im1bw = ones(size(im1)); % mask1
im2bw = ones(size(im2)); % mask2
im1bwt=imwarp(im1bw,transform_eye,'OutputView',RF); % im1 stays in place (identity transform)
im2bwt=imwarp(im2bw,transform,'OutputView',RF); % im2 is transformed
% visualize result
maskOverlap = im1bwt + im2bwt - 1;
imshow(maskOverlap);
% maskOverlap is a bw image that contains 'true' for overlap pixels
% you can use that for cropping imOverlay or
% use bwarea or regionprops to calculate the area

Related

How to classify objects with different number of holes?

My object is classifying cells in the given image. Classification is based on the shape and number of the nucleus(holes). Some of the cells have a circular type while others not. Some of has one hole (nucleus), while others have more.
After some clearing and preprocessing, I have classified circular and overlapped cells so far. But there is a cell with two holes(nucleus) which should belong to another class. But I couldn't do it. If I can count the number of holes, I think I can classify also that cell.
im =imread('blood.jpg'); % Reading target image
figure(1),imshow(im), title('Original Image');
imGray = rgb2gray(im); % Converting image RGB to gray-level (2-Dimensional).
gray_thresh = graythresh(imGray);
bw = im2bw(imGray, gray_thresh); figure(2), imshow(bw), title('Binary Image'); % Converting image to binary.
bw = imcomplement(bw); % Taking image's complement.
figure(3), imshow(bw), title('Complement of Image');
%bw=imfill(bw,'holes');
bw = imclearborder(bw);
figure(4), imshow(bw), title('Objects touching image borders removed');
bw = bwareaopen(bw,500); % Remove objects smaller than 500px.
figure(5),imshow(bw); title('Small objects removed');
label = bwlabel(bw);
[B,L] = bwboundaries(bw,'noholes');
stats = regionprops(L,'Area','Centroid');
threshold = 0.70;
figure(6), imshow(bw)
hold on
for k = 1:length(B)
% obtain (X,Y) boundary coordinates corresponding to label 'k'
boundary = B{k};
% compute a simple estimate of the object's perimeter
delta_sq = diff(boundary).^2;
perimeter = sum(sqrt(sum(delta_sq,2)));
% obtain the area calculation corresponding to label 'k'
area = stats(k).Area;
% compute the roundness metric
metric = 4*pi*area/perimeter^2;
if metric > threshold
plot(boundary(:,2),boundary(:,1),'r','LineWidth',2)
%Circular
else
plot(boundary(:,2),boundary(:,1),'g','LineWidth',2)
%Overlapped
end
end
Cell with two nucleus(holes)

How can I select the inner center square region of 100x100 pixels of an image in octave?

I want to select the inner center region of an image and insert that into the center of another image .
Find the centres of both images.Evaluate the subregion and find corresponding indices around the centres.Use those indices to reference one image and assign into the other.e.g.
%% example images
img1 = magic (100);
img2 = randi (10000, [80, 60]);
%%
c1 = floor (size (img1) / 2).'; % centre point of img1 as vector
c2 = floor (size (img2) / 2).'; % centre point of img2 as vector
sub = [50, 30].'; % size of desired sub-region as vector
%% safety first!
assert (sub <= size (img1).' && sub <= size (img2).', ...
'Subregion must be smaller than the images it is applied to');
%%
ind1 = [c1 - (sub/2), c1 + (sub/2)]; % corresponding indices for img1
ind2 = [c2 - (sub/2), c2 + (sub/2)]; % corresponding indices for img2
%% create new image from img1, assign subregion from img2 in the right location
New = img1;
New( ind1(1,1) : ind1(1,2), ind1(2,1) : ind1(2,2) ) = ...
img2(ind2(1,1) : ind2(1,2), ind2(2,1) : ind2(2,2));
%% see the result
imagesc(New)
Ideally create a function that does this for you in general; that final
indexing operation is quite ugly.
color_img = imread('test.jpg'); % read the first image
[y, x, z] = size(color_img); % find the sizes
rect = [(x/2)-50, (y/2)-50, 99, 99]; % form a rectangle for cropping
I2 = imcrop(color_img,rect); % crop it
another_image = imread('test1.jpg'); % read another image
[y1, x1, z1]=size(another_image); % find the size of another image
subrect = [(x1/2)-50, (y1/2)-50, 99, 99]; % form a rectangle for cropping
subI2 = padarray(imcrop(another_image,subrect), [y1/2-50, x1/2-50]); % padd the zeros to cropped one to make main image and cropped image of equal size
antimg = another_image - subI2; % make center area zeros in another image
new = padarray(I2, [y1/2-50, x1/2-50]); % padd zeros to cropped one from first image to make it equal to size of another image
new1 = imadd(new, antimg); % add cropped of older image to new image(which has zeros at center due to substraction)
% show the result
imshow(new1)
This solution works for non-equal resolutions as well.

Convert Matlab code into Simulink

I would like to convert a image processing program(part of the program below) from Matlab to Simulink and possibly convert the simulink diagram into C code later on. I have 0 experience in Simulink and was wondering if there's any limitations on the types of matlab program/functions that can be converted and how I would go about doing this. Thanks.
clear all
clc
% Read in an image 1
C1 = imread('cloud1.jpg');
Cloud1 = C1(:,:,1); % use only one color
%Cloud1 = Cloud1'; % transpose to get (x,y) instead of (y,x)
Cloud1_xsize = size(Cloud1,2); % get x size of image
Cloud1_ysize = size(Cloud1,1); % get y size of image
%figure(3), imshow(Cloud1) % to plot you need to transpose back to their coordinate system
%hold on
% Read in an image 2
C2 = imread('cloud2.jpg');
Cloud2 = C2(:,:,1); % use only one color
%Cloud2 = Cloud2'; % transpose to get (x,y) instead of (y,x)
Cloud2_xsize = size(Cloud2,2); % get x size of image
Cloud2_ysize = size(Cloud2,1); % get y size of image
%figure(2), imshow(Cloud2)
%hold on
% show the shift in the initial images several times
num = 0;
for k = 1:4
num=num+1;
pause(.5)
figure(1), h1=imshow(C1)
xlabel('FIGURE 1')
F(num) = getframe(gcf);
%image(F.cdata)
%colormap(F.colormap)
pause(0.25)
figure(1), h2=imshow(C2)
xlabel('FIGURE 2')
num=num+1;
F(num) = getframe(gcf);
%image(F.cdata)
%colormap(F.colormap)
end
% Play the movie twenty times
%movie(F,20)
%%%% Set the template size %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% First calc the number of pixels in the shortest direction of the image (usually y direction)
MinSize = min(Cloud1_xsize, Cloud1_ysize); % number of pixels in shortest direction
%%% N is the minimum number of boxes in the shorter direction (usually y direction).
%%% In the shorter axis (usually y)there will be N-2 boxes analyzed.
%%% This is because the top and bottom boxes are considered too close to the edge to use.
%%% In the larger direction (usually x) there may be more boxes.
N = 6;
EdgeBoxSize = 1; % the number of edge boxes along each edge
TempWidth = floor(MinSize / N); % the pixel width of each template box
TempHeight = TempWidth; % make the template height and width the same size so corr part works good
%%% Now calculate the exact number of boxes in x and y directions
%%% This depends on the number of x versus y pixels.
Nx = floor(Cloud1_xsize/TempWidth);
Ny = floor(Cloud1_ysize/TempWidth);

Matlab and ImageJ detecting bone fracture

I'm trying to detect a fracture in a picture using imageJ and Matlab, both of them are required. Here is the original image:
I already established the connection between matlab and imageJ and I've opened the image on imageJ and started by doing some things. First, I used the Find Edges function in imageJ menu to get an outline of the bone. After I did a constrast enhancement to enhance the outline. My problem now is, having only an outline and a black background how can I make an algorithm or something like it that will tell me that the lines don't connect? (meaning there is a fracture in the bone). I did something similar to what is on this video in the part when he ticks the sobel edge detection.
https://www.youtube.com/watch?v=Hxn2atZl5us
Gave it a shot in MATLAB only. You can use the Hough transform to find what the largest-contributing angles are to the edge-filtered image, then use that information to go one step more and detect where the break is with some typical image processing tricks.
No promises on how this will work on any images that are not the one that you provided, but the steps are reasonable to refine for additional sample breadth.
img = imread('http://i.stack.imgur.com/mHo7s.jpg');
ImgBlurSigma = 2; % Amount to denoise input image
MinHoughPeakDistance = 5; % Distance between peaks in Hough transform angle detection
HoughConvolutionLength = 40; % Length of line to use to detect bone regions
HoughConvolutionDilate = 2; % Amount to dilate kernel for bone detection
BreakLineTolerance = 0.25; % Tolerance for bone end detection
breakPointDilate = 6; % Amount to dilate detected bone end points
%%%%%%%%%%%%%%%%%%%%%%%
img = (rgb2gray(img)); % Load image
img = imfilter(img, fspecial('gaussian', 10, ImgBlurSigma), 'symmetric'); % Denoise
% Do edge detection to find bone edges in image
% Filter out all but the two longest lines
% This feature may need to be changed if break is not in middle of bone
boneEdges = edge(img, 'canny');
boneEdges = bwmorph(boneEdges, 'close');
edgeRegs = regionprops(boneEdges, 'Area', 'PixelIdxList');
AreaList = sort(vertcat(edgeRegs.Area), 'descend');
edgeRegs(~ismember(vertcat(edgeRegs.Area), AreaList(1:2))) = [];
edgeImg = zeros(size(img, 1), size(img,2));
edgeImg(vertcat(edgeRegs.PixelIdxList)) = 1;
% Do hough transform on edge image to find angles at which bone pieces are
% found
% Use max value of Hough transform vs angle to find angles at which lines
% are oriented. If there is more than one major angle contribution there
% will be two peaks detected but only one peak if there is only one major
% angle contribution (ie peaks here = number of located bones = Number of
% breaks + 1)
[H,T,R] = hough(edgeImg,'RhoResolution',1,'Theta',-90:2:89.5);
maxHough = max(H, [], 1);
HoughThresh = (max(maxHough) - min(maxHough))/2 + min(maxHough);
[~, HoughPeaks] = findpeaks(maxHough,'MINPEAKHEIGHT',HoughThresh, 'MinPeakDistance', MinHoughPeakDistance);
% Plot Hough detection results
figure(1)
plot(T, maxHough);
hold on
plot([min(T) max(T)], [HoughThresh, HoughThresh], 'r');
plot(T(HoughPeaks), maxHough(HoughPeaks), 'rx', 'MarkerSize', 12, 'LineWidth', 2);
hold off
xlabel('Theta Value'); ylabel('Max Hough Transform');
legend({'Max Hough Transform', 'Hough Peak Threshold', 'Detected Peak'});
% Locate site of break
if numel(HoughPeaks) > 1;
BreakStack = zeros(size(img, 1), size(img, 2), numel(HoughPeaks));
% Convolute edge image with line of detected angle from hough transform
for m = 1:numel(HoughPeaks);
boneKernel = strel('line', HoughConvolutionLength, T(HoughPeaks(m)));
kern = double(bwmorph(boneKernel.getnhood(), 'dilate', HoughConvolutionDilate));
BreakStack(:,:,m) = imfilter(edgeImg, kern).*edgeImg;
end
% Take difference between convolution images. Where this crosses zero
% (within tolerance) should be where the break is. Have to filter out
% regions elsewhere where the bone simply ends.
brImg = abs(diff(BreakStack, 1, 3)) < BreakLineTolerance*max(BreakStack(:)) & edgeImg > 0;
[BpY, BpX] = find(abs(diff(BreakStack, 1, 3)) < BreakLineTolerance*max(BreakStack(:)) & edgeImg > 0);
brImg = bwmorph(brImg, 'dilate', breakPointDilate);
brReg = regionprops(brImg, 'Area', 'MajorAxisLength', 'MinorAxisLength', ...
'Orientation', 'Centroid');
brReg(vertcat(brReg.Area) ~= max(vertcat(brReg.Area))) = [];
% Calculate bounding ellipse
brReg.EllipseCoords = zeros(100, 2);
t = linspace(0, 2*pi, 100);
brReg.EllipseCoords(:,1) = brReg.Centroid(1) + brReg.MajorAxisLength/2*cos(t - brReg.Orientation);
brReg.EllipseCoords(:,2) = brReg.Centroid(2) + brReg.MinorAxisLength/2*sin(t - brReg.Orientation);
else
brReg = [];
end
% Draw ellipse around break location
figure(2)
imshow(img)
hold on
colormap('gray')
if ~isempty(brReg)
plot(brReg.EllipseCoords(:,1), brReg.EllipseCoords(:,2), 'r');
end
hold off

how to detect optic disc in retinal images using matlab

enter code here
% Finding mean for 49*49 sub images
meanmat=ones(209,209);
k=1;count=1;
[m n]=size(BW);
for i=25:1:m-24
for j=25:1:n-24
rowst=i-24;rowend=i+24;
colst=j-24;
colend=j+24;
summat=0;
for row=rowst:1:rowend
for col=colst:1:colend
summat=summat+BW(row,col);
end
end
meanval=(summat)/(49*49);
meanmat(k,count)=meanval;
if(count>208)
count=1;k=k+1;
else
count=count+1;
end
end
end
% mean and median filter
I = im2double(BW);
kernel = ones(80,80) / (80*80); % 49*49 mean kernel
J = conv2(I, kernel, 'same'); % Convolve keeping size of I
stdDevImage = stdfilt(BW);
varianceIMage = stdDevImage .^2;
figure,subplot(2,2,1);
imshow(BW);title('Original');
subplot(2,2,2);
imshow(meanmat);title(sprintf('MeanImage'));
subplot(2,2,3);
imshow(varianceIMage);title(sprintf('variance using stdfilt'));
subplot(2,2,4);
imshow(J);title(sprintf('Average Variance using conv2'));
I have calculated mean,variance and average variance for the image using the above code.But the optic disc was not detected properly.Can anyone help me with the matlab code for finding the optic disc?
%% Initial Image Processing.
% get image and mode from workspace
Im = evalin('base','Im');
singlemode = evalin('base','singlemode');
% apply filter on green component
f1 = fspecial('average',31); % create averaging filter
IMA = imadjust(Im(:,:,2)); % adjust green component intensity first
Imf = filter2(f1,IMA); % apply filter
Imf = mat2gray(Imf); % convert back from (0,1) to (0,255)
axes(handles.axes2); % show grayscale filtered image
imshow(Imf);
%% Edge Detection.
thrsh = str2num(get(handles.edit1,'String')); % default = 0.98
Ibw=im2bw(Imf,thrsh); % binary mask / black & white threshold
I_edge = edge(Ibw); % edge detection
% axes(handles.axes3);
% imshow(I_edge); % show image
%% Circular Hough transform to detect optical disc (OD).
% Rmin = str2num(get(handles.edit3,'String')); % minimum radius from user input
% Rmax = str2num(get(handles.edit4,'String')); % maximum radius from user input
Rmin = 80;
Rmax = 120;
radii = Rmin:5:Rmax; % radii to check
h = circle_hough(I_edge,radii,'same','normalise');
peaks = circle_houghpeaks(h,radii,'nhoodxy',2*(Rmax/2)+1,'nhoodr',5,'npeaks',1); % find the peaks in the transform, meaning find the best fit of a circle. and we only want 1 circle.
% Lines 196 -207 - if we're in single mode, we're plotting the circle in the top left image
if singlemode
axes(handles.axes1);
imshow(Im);
hold on
for peak = peaks
[x y] = circlepoints(peak(3)); % This function returns the x,y coordinates of the found circle, peak(3) is the radius of the found circle.
plot(x+peak(1),y+peak(2),'b-'); % we plot the x,y coordinates shifted by the center of the circle, which are peak(1) and peak(2)
end
plot(peak(1),peak(2),'r+'); % We plot the center of the circle with a red cross.
hold off
end
axes(handles.axes2); % Lines 208 - 214, we repeat the plot of the circle into axes2, the top right figure
hold on
for peak = peaks
[x y] = circlepoints(peak(3));
plot(x+peak(1),y+peak(2),'b-');
end
hold off
%% Region of Interest (ROI) Processing.
% we have localized the OD, define the ROI around this position for further
% processing.
axes(handles.axes2); % Activate axes2.
e = imellipse(gca,[peak(1)-2*peak(3) peak(2)-2*peak(3) 4*peak(3) 4*peak(3)]); %get an elliptical sub image centered around the peak(1) and peak(2) values (the centers of the previously found OD) and 2 times the radius that was found previously.
BW = createMask(e); % Create a mask from this region of interest = ROI.
Imf_masked = Imf.*BW; % Apply mask to the image, this will make everything outside of the ROI become black.
% axes(handles.axes4);
% imshow(Imf_masked);
thrsh = str2num(get(handles.edit5,'String')); % get threshold for ROI hough transform from the GUI, default = 0.65
Ibw=im2bw(Imf_masked,thrsh); % binary mask / black & white threshold (threshold the masked image).
I_edge = edge(Ibw); % edge detection
% axes(handles.axes3);
% imshow(I_edge); % show image
% hough transform to find circle in the ROI
h = circle_hough(I_edge,radii,'same','normalise');
peaks = circle_houghpeaks(h,radii,'nhoodxy',2*(Rmax/2)+1,'nhoodr',5,'npeaks',1);
if singlemode
axes(handles.axes1);
hold on
for peak = peaks
[x y] = circlepoints(peak(3));
plot(x+peak(1),y+peak(2),'g-');
end
plot(peak(1),peak(2),'g+');
hold off
end