I need to find similar corners in image (for example: 4 corners of a rectangle, same corners, just different orientation?).
I have this code:
% read the image into MATLAB and convert it to grayscale
I = imread('s2.jpg');
Igray = rgb2gray(I);
figure, imshow(I);
% We can see that the image is noisy. We will clean it up with a few
% morphological operations
Ibw = im2bw(Igray,graythresh(Igray));
se = strel('line',3,90);
cleanI = imdilate(~Ibw,se);
figure, imshow(cleanI);
% Perform a Hough Transform on the image
% The Hough Transform identifies lines in an image
[H,theta,rho] = hough(cleanI);
peaks = houghpeaks(H,10);
lines = houghlines(Ibw,theta,rho,peaks);
figure, imshow(cleanI)
% Highlight (by changing color) the lines found by MATLAB
hold on
After running this code I convert my starting image into a binary image with:
binary = im2bw(I);
after this I get a product from those 2 binary images and I think I get corners..
product = binary .* cleanI;
now I imfuse this picture with grayscale starting picture and get this:
I dont know what to do to get only those 4 corners!
Ok second try. Below a code that does not finally do the job but it might help.
Edge identifies the contours and with regionprops you get the characteristica of each identified element. As soon as you know what characteristics your desired object has you can filter it and plot it. I went through the Areas in shapedata.Area and the 6th largest was the one you were searching for. If you combine Area with some of the other charateristica you might get the one you want. As I said not ideal and final but perhaps a start ...
clear all
close all
source = imread('Mobile Phone.jpg');
im = rgb2gray(source);
bw = edge(im ,'canny',[],sqrt(2));
shapedata=regionprops (bwlabel(bw,8),'all');
%index = find([shapedata.Area]== max([shapedata.Area]));
index = 213;
data = shapedata(index).PixelList;
figure
imshow(im)
hold on
plot(data(:,1),data(:,2),'ro');
Related
I have this problem in image processing and I couldn't find an algorithm to perform well under this condition.It's so simple to understand but I don't know how to implement it in OpenCV or in Matlab, so any algorithm or function in one of them (MATLAB or opencv) is helpful.
1 . lets suppose that an image and background of scene is like the below
2 . We apply an edge detector to image and my current image will be like the below picture.
now my Problem is that how we can find the biggest contour or area like the below in edge image?
If you want original picture the original picture is
and in matlab you can get edge image by below codes.
clc
clear
img = imread('1.png'); % read Image
gray = rgb2gray(img); % Convert RGB to gray-scale
edgeImage = edge(gray,'canny',0.09); % apply canny to gray-scale image
imshow(edgeImage) % Display result in figure(MATLAB)
In OpenCV you can use below code
#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
Mat img = imread("1.png");
Mat gray;
cvtColor(img, //BGR form image
gray, //Mat for gray(destination)
CV_BGR2GRAY); //type of transform(in here BGR->GRay)
Mat edgeImage;
Canny(gray, //Input Array
edgeImage, //Output Array
40, // Lower threshold
120); //Upper threshold
namedWindow("Edge-Image"); //create a window for display image
imshow("Edge-Image",edgeImage); //Display edgeImage in window that in before line create
waitKey(0); //stick display window and wait for any key
return 0;
}
Here is a solution in Matlab using imdilate to close the contours and regionprops to get the closed objects area:
% Your code to start
img = imread('Image.png'); % read Image
gray = rgb2gray(img); % Convert RGB to gray-scale
edgeImage = edge(gray,'canny',0.09); % apply canny to gray-scale image
% First dilate to close contours
BW = imdilate(edgeImage, strel('disk',4,8));
% Then find the regions
R = regionprops(~BW, {'Area', 'PixelIdxList'});
% Find the second biggest region (the biggest is the background)
[~, I] = sort([R(:).Area], 'descend');
Mask = zeros(size(img));
Mask(R(I(2)).PixelIdxList) = 1;
% Display
clf
imshow(Mask)
An the result is:
Best,
First close the contour with morphological closing since you can't find it now as it is not really a distinct contour, but a part of the larger one.
After closing, just use the findContours() function and use its output to get the area of each contour and eventually find the maximum one by using the contourArea() function.
I'm using the watershed algorithm to segment bright spots on a dark background. The code is provided below, along with some images it generates.
In the second image, I've marked with red crosses the areas of enclosed background which are segmented as 'cells' (they're not biological cells, just using the word) - this is incorrect, they're part of the background, just enclosed by 'cells'. I see that this creates a false minimum, any help on how to prevent this?
% Improve contrast, binarize
RFP_adjust = imadjust(RFP_blur, stretchlim(RFP_blur, 0.001));
figure, imshow(RFP_adjust), title('Contrast adjust');
RFP_binarized = imbinarize(RFP_adjust);
RFP_perimeters = bwperim(RFP_binarized);
% figure, imshow(RFP_binarized), title('Otsu thresholding');
%2B - SEGMENTATION BY WATERSHED METHOD
% Discover putative cell centroids and process
RFP_maxs = imextendedmax(RFP_adjust, 3000);
RFP_maxs = imclose(RFP_maxs, strel('disk',5));
RFP_maxs = imfill(RFP_maxs, 'holes');
RFP_maxs = bwareaopen(RFP_maxs, 5);
RFP_max_overlay = imoverlay(RFP_adjust, RFP_perimeters | RFP_maxs, [1 .3 .3]);
figure, imshow(RFP_max_overlay), title('Maxima');
% Obtain complement - maxima become low-points (required for watershed)
RFP_comp = imcomplement(RFP_adjust);
RFP_imposemin = imimposemin(RFP_comp, ~RFP_binarized | RFP_maxs);
figure, imshow(RFP_imposemin), title('Inverted Maxima');
% Apply watershed
RFP_watershed = watershed(RFP_imposemin);
mask = im2bw(RFP_watershed, 1);
overlay3 = imoverlay(RFP_adjust, mask, [1 .3 .3]);
figure, imshow(overlay3), title('Segmented cells');
% Segment
RFP_cc = bwconncomp(RFP_watershed);
RFP_label_matrix = labelmatrix(RFP_cc);
whos labeled;
RFP_label = label2rgb(RFP_label_matrix, #spring, 'c', 'shuffle');
figure, imshow(RFP_label), title('Cells segmented');
Image 0 - result for image titled 'Maxima' (i.e. adjusted original image with maxima and outlines overlaid).
Image 1 - the result for image titled 'inverted maxima'
Image 2 - the result for image titled 'Cells segmented'
I would suggest something like what is done in the example included for the watershed function: use the background mask to set those pixels to Inf, perform the watershed operation, then set the background pixels in the result to 0. I believe you could change the watershed section of your code like so to achieve this:
% Apply watershed
RFP_watershed = RFP_imposemin; % Added
RFP_watershed(~RFP_binarized) = Inf; % Added
RFP_watershed = watershed(RFP_watershed); % Modified
RFP_watershed(~RFP_binarized) = 0; % Added
mask = im2bw(RFP_watershed, 1);
overlay3 = imoverlay(RFP_adjust, mask, [1 .3 .3]);
figure, imshow(overlay3), title('Segmented cells');
There no magic bullet, but a few things you can try.
One is to filter the image with a very large circular disc, creating a blurry image that looks like the background. Then subtract it from the original image. That will tend to force the actual background to zero.
Another is to Otsu threshold to separate foreground from background. That creates a binary image. Then do a morphological open operation using a mask designed to look like the actual cells.
Hello I have a work on this image:
My objective is to count all the sperm in this image .for this I'm thinking to detect just the lines so it make my work easy. because I am beginner, in this step I am completely lost there are any algorithms can help me to detect lines?? ( I have seen that there are hough transformation and scan line algorithm) I don't which algorithm can help me and if there are others
Here's a piece of code that might help you getting started.
By looking at the image it seems very difficult to label sperms by looking at straight lines and hence using Hough transform won't help a lot.
In the example below I focused on filtering the image and counting the number of blobs. The code is commented and should be easy to understand.
img = imread('d9S3Z.png');
figure, imshow(img)
% convert to binary image
[X,map] = rgb2ind(img,0.0);
img = ind2gray(X,map); % Convert indexed to grayscale
level = graythresh(img); % Compute an appropriate threshold
% or use your own, e.g. level = 0.46
img_bw = im2bw(img,level);% Convert grayscale to binary
% create mask to remove edge interference
mask = zeros(size(img_bw));
mask(2:end-2,2:end-2) = 1;
img_bw(mask<1) = 1;
%invert image
img_inv =1-img_bw;
% find blobs
img_blobs = bwmorph(img_inv,'majority',10);
figure, imshow(img_blobs);
% count blobs
CC = bwconncomp(img_blobs);
num_sperm = CC.NumObjects # sperm count
I have an image that has multi frequency noise, I used the code in this link :
Find proper notch filter to remove pattern from image
source image : orig_image
But my final image noise has not been removed.
As you know, I must remove the gradient in vertical direction. the frequency representation of image come in below:
fft of image
Have anyone idea for removal of this noise in matlab?
I apply sobel filter and median filter but not improved.
Note that my goal is remove of lines inside of object.
Regards.
You have two kinds of noise: irregular horizontal lines and salt and pepper. Getting rid of the lines is easy as long as the object doesn't cover the whole horizontal range (which it doesn't in your example).
I just sample a small vertical stripe on the left to only get the stripes and then subtract them from the whole image. Removing the salt and pepper noise is simple with a median filter.
Result:
Code:
% read the image
img = imread('http://i.stack.imgur.com/zBEFP.png');
img = double(img(:, :, 1)); % PNG is uint8 RGB
% take mean of columsn 100..200 and subtract from all columns
lines = mean(img(:, 100:200), 2);
img = img - repmat(lines, 1, size(img, 2));
% remove salt and pepper noise
img =medfilt2(img, [3,3], 'symmetric');
% display and save
imagesc(img); axis image; colormap(gray);
imwrite((img - min(img(:))) / (max(img(:)) - min(img(:))), 'car.png');
here is code I once used for an assignment I once had to do. It was a much simpler example than the one you have. There were only a total of 4 components in the frequency domain causing noise, so simply setting those 4 components to zero manually (hfreq) solved my problem. I dont know how well this will work in your case, perhaps writing an algorithm to find the appropriate hfreqs that stand out will help. Here was the original image I used :
This is the code I used :
% filtering out the noisy image
clc
clear all
close all
image = imread('freqnoisy.png');
image = double(image);
image = image/(max(max(image)));
imshow(image) % show original image
Fimage = fft2(image);
figure
imshow(((fftshift(abs(Fimage)))),[0 5000]) %shows all frequency peaks that stick out
hfreq = ones(256);
hfreq(193,193)=0;
hfreq(65,65) = 0;
hfreq(119,105) = 0;
hfreq(139,153)= 0;
%
Fimage_filtered = fftshift(Fimage).*hfreq;
figure
imshow(abs(Fimage_filtered),[0 5000]) % show freq domain without undesired freq
filtered_im = ifft2(ifftshift(Fimage_filtered));
figure
imshow(filtered_im)
this is what your output will look like :
I have an image of licence plate and the numbers is marked with black squares.
what I want is to get all the coordinates of the squares, and with it to cut them from the plate.
for example this is the original image:
and this is after marking the numbers:
any help will be greatly appreciated.
Here's one way to do it in Matlab
%# read the first image
img = imread('http://i.stack.imgur.com/s9A4m.jpg');
%# convert it to a binary image
img = rgb2gray(img);
img = img > 200;
%# remove the connecting lines
img = imclose(img,strel('disk',5));
%# use bwlabel to replace the black squares with a index (1,2,3...)
lblImg = bwlabel(~img);
%# read the second image, make it binary
img2 = imread('http://i.stack.imgur.com/PtKzw.jpg');
img2 = img2 > 200;
%# create the output - each number is now labeled with an index
out = double(~img2).*lblImg;
%# visualize all
figure,imshow(label2rgb(out,'jet','k','shuffle'))
%# extract and show label #1
firstNumber = out==1;
imshow(firstNumber);
I don't do Matlab, but I can show you how to do it in Mathematica. Hopefully you can translate!
Have a look at the image processing toolbox.
The functions bwdist, imregionalmin and bwselect should be able to get you the square coordinates.
Sketch answer as I'm in a rush. You have some white dots in the squares and some black streaks connecting the squares. Look up the morphological operations such as:
http://www.mathworks.com/help/toolbox/images/ref/imclose.html
Close the image with a small structuring element (3x3 square or similar) to get rid of the bits of noise in the squares.
Open the image with a larger structuring element (10x10 square or bigger) get rid of the connecting streaky bits.
Then use a function like bwlabel to segment/label the remaining pixels. This is a little imprecise as the squares will lose some of the structure at the edges.