I'm looking for some ideas to detect lines in the attached image. Lines are assumed to be vertical, but their are very poor quality and there are only 2-3 pixels between each blurry line.
I tried these methods already:
Erosion& Dilation in vertical ->good result for enhancement
CLAHE -> Good for enhancement
Hough -> Failed since converting the images to Black & while will have too many broken lines or bridges.
Also I tried vertical line Mask too.
Basically methods based on Black&White image conversion won't be applicable for this.
I would collapse the image along the lines to get 1d profile. And do the detection there (e.g. by looking at the peaks above the median.
Here is the collapsed image
The object detection there is obvious
Very promising works regarding faint edges detection in noisy images:
Basic version for straight lines:
http://www.wisdom.weizmann.ac.il/~meirav/EdgesGalunBasriBrandt.pdf
More advanced version:
http://www.wisdom.weizmann.ac.il/~meirav/Curves_Alpert_Galun_Nadler_Basri.pdf
I'm not sure if the authors made their code publicly available. It might be worth-while contacting the authors directly.
These works proposes a well studied and principled method for faint-edge detection.
Here's an alternative approach, that will find you the lines, assuming that the peak is apparent within ~5 pixels. It will be tolerant to small rotations of the image.
img = imread('http://i.stack.imgur.com/w7qMT.jpg');
img = rgb2gray(img);
%# smoothen the image a little with an anisotroic Gaussian
fimg = imfilter(double(img),fspecial('gaussian',[3 1]));
%# find the lines as local maxima
msk = ones(5);
msk(:,2:4) = 0;
lines = fimg > imdilate(fimg,msk);
Related
How to detect such cracks that you can see in the attached images? I have tried some OpenCV algorithms like blob detection (cv::SimpleBlobDetector) but couldn't get any results.
It is a cropped image, the full image has some other features as well, so I am not sure thresholding can work because I have to get the bounding box of the detected crack. One way is to assign several (region of interest) ROI and try to detect within that ROI, but this crack doesn't appear at the same location in the image. Any idea?
Can this problem be solved with machine/deep learning (like object detection)? If I train a model with a crack dataset? Because the crack part of the image doesn't have lots of features so I am not sure this method will work. Please guide.
Thanks.
These cracks are difficult to detect because the image is noisy (presumably X-ray) and the contrast poor, so the signal-to-noise ratio is low.
I would try by applying a gaussian filter for denoising, but only in the horizontal direction, to preserve the horizontal edges. Then detection of the horizontal edges.
This is about what a Gabor filter does. You can try different orientations.
Use mathematical morphology operation.
By example Matlab code:
a=imread('in.png');
se=strel( 'disk', 7);
b = imgaussfilt(a,1.3);
c=b-imopen(b,se);
c=3*c;
d=imclearborder(c);
imwrite(d, 'out.png');
I am a new user on image processing via Matlab. My first aim is applying the article and comparing my results and authors' results.
The article can be found here: http://arxiv.org/ftp/arxiv/papers/1306/1306.0139.pdf
First problem, Image Quality: In Figure 7, masks are defined but I couldn't reach the mask data set, and I use the screenshot so image quality is low. In my view, it can effect the results. Is there any suggestions?
Second problem, Merging images: I want to apply mask 1 on the Lena. But I don't want to use paint =) On the other hand, is it possible merging the images and keeping the lena?
You need to create the mask array. The first step is probably to turn your captured image from Figure 7 into a black and white image:
Mask = im2bw(Figure7, 0.5);
Now the background (white) is all 1 and the black line (or text) is 0.
Let's make sure your image of Lena that you got from imread is actually grayscale:
LenaGray = rgb2gray(Lena);
Finally, apply your mask on Lena:
LenaAndMask = LenaGray.*Mask;
Of course, this last line won't work if Lena and Figure7 don't have the same size, but this should be an easy fix.
First of all, You have to know that this paper is published in archive. when papers published in archive it is always a good idea to know more about the author and/or the university that published the paper.
TRUST me on that: you do not need to waste your time on this paper.
I understand your demand: but it is not a good idea to do get the mask by doing print screen. The pixel values that can be achieved by using print screen may not be the same as the original values. The zoom may change the size. so you need to be sure that the sizes are the same.
you can do print screen. past the image.
crop the mask.
convert rgb to gray scale.
threshold the gray scale to get the binary.
if you saved the image as jpeg. distortions because of high frequency edges will change edge shape.
I found that there are some paper said can analysis the gradient histogram
(blur image has gradient follows a heavy-tailed distribution)
or using fft (blur image has lower frequency)
Is there a way to detect if an image is blurry?
to detect blur in image.
But I am not quite sure how to implement it in matlab. How to define the threshold value and so on.
[Gx, Gy] = imgradientxy(a);
G = sqrt(Gx.^2+Gy.^2)
What should I do after running the command and find the G?
What should I do if I wanna plot a graph of number of pixel verse G
I am new to matlab and image processing. Could anyone kindly provide more details of how to implement it
Preparation: we read the cameraman image, which is often used for visualizing image processing algorithms, and add some motion blur.
origIm = imread('cameraman.tif');
littleBlurredIm = imfilter(origIm,fspecial('motion',5,45),'replicate');
muchBlurredIm = imfilter(origIm,fspecial('motion',20,45),'replicate');
which gives us the following images to start with:
To calculate the Laplacian, you can use the imgradient function, which returns magnitude and angle, so we'll simply discard the angle:
[lpOrigIm,~] = imgradient(origIm);
[lpLittleBlurredIm,~] = imgradient(littleBlurredIm);
[lpMuchBlurredIm,~] = imgradient(muchBlurredIm);
which gives:
You can visually see that the original image has very sharp and clear edges. The image with a little blur still has some features, and the image with much blur only contains a few non-zero values.
As proposed in the answer by nikie to this question, we can now create some measure for the blurriness. A (more or less) robust measure would for example be the median of the top 0.1% of the values:
% Number of pixels to look at: 0.1%
nPx = round(0.001*numel(origIm));
% Sort values to pick top values
sortedOrigIm = sort(lpOrigIm(:));
sortedLittleBlurredIm = sort(lpLittleBlurredIm(:));
sortedMuchBlurredIm = sort(lpMuchBlurredIm(:));
% Calculate measure
measureOrigIm = median(sortedOrigIm(end-nPx+1:end));
measureLittleBlurredIm = median(sortedLittleBlurredIm(end-nPx+1:end));
measureMuchBlurredIm = median(sortedMuchBlurredIm(end-nPx+1:end));
Which gives the following results:
Original image: 823.7
Little Blurred image: 593.1
Much Blurred image: 490.3
Here is a comparison of this blurriness measure for different motion blur angles and blur amplitudes.
Finally, I tried it on the test images from the answer linked above:
which gives
Interpretation: As you see it is possible to detect, if an image is blurred. It however appears difficult to detect how strongly blurred the image is, as this also depends on the angle of the blur with relation to the scene, and due to the imperfect gradient calculation. Further the absolute value is very much scene-dependent, so you might have to put some prior knowledge about the scene into the interpretation of this value.
This is a very interesting topic.
Although gradient magnitude can be used as good feature for blur detection but this feature will fail when dealing with uniform regions in images. In other words, this feature will not be able to distinguish between blur and flat regions. There are many other solutions. Some of them detect flat regions to avoid classifying flat regions as blur. if you want more information you can check these links:
You can find many good recent papers in cvpr conference.
Many of them they have websites where they discuss the details and provide the code.
This one http://www.cse.cuhk.edu.hk/leojia/projects/dblurdetect/
is one of the papers that I worked on
you can find the code available.
You can check also other papers in cvpr. most of them they have the code
this is another one
http://shijianping.me/jnb/index.html
I would like to know something about wrinkles detection in Matlab:
I thought of using Hough Transform but it could not work for this. Is there any idea that I could processed further?
I even thought of using sobe, canny and other edge detector. But when I read their documentation, they are not really an edge detector.
close all
clear all
clc
Image = imread('imagename.jpg');
GrayImage = rgb2gray(Image);
FiltImage = edge(GrayImage ,'sobel');
imshow(FiltImage)
i want all the wrinkles as white pixel and the rest of the image as black.
I borrowed the method used in vessel detection from the paper Hessian-based Multiscale Vessel Enhancement Filtering by Frangi et al. There is a Matlab implementation, FrangiFilter2D, that works on 2D vessel images. And I tried to apply it to wrinkle detection.
options = struct('FrangiScaleRange', [5 5], 'FrangiScaleRatio', 1, 'FrangiBetaOne', 1,...
'FrangiBetaTwo', 500, 'verbose',true,'BlackWhite',true);
[outIm,whatScale,Direction] = FrangiFilter2D(double(GrayImage), options);
imshow(uint8(outIm/max(outIm(:))*256))
It looks better than pure edge extraction, though some improvement is need by (i) tuning the parameters, and (ii) combining with other image processing strategies.
Matlab has a ton of fun tools that you can essentially play with in combination, to detect the wrinkles. Here are some things to look at.
1). Study thresholding and see how it applies to your situation (this will help you a lot because of the contrast that exists between the wrinkles and the rest of the face color).
2). Remember you can add and subtract images.
3).Study watershed algorithm if you feel adventurous.
Hello,
I have a segmented image as shown. Is there a way to smoothen the lines so that it does not look so wavy? Thanks.
The following code requires Image Processing Toolbox:
url = 'http://i182.photobucket.com/albums/x11/veronicafmy/FYP/picture5segmentedimage.jpg';
rgb = imread(url);
bw = im2bw(rgb2gray(rgb), 0.5);
se = strel('line',50,74); % 74 degrees determined by inspection
bw2 = imclose(bw,se);
se2 = strel('line',50,74+90);
bw3 = imclose(bw2,se2);
Here's the result:
Optional step: postprocess by thinning:
bw4 = bwmorph(bw3,'thin',inf);
I think you should ask yourself why it has to be smoother. If you have segmented an image and gotten that result, are you sure that smoothening will give you a correct result?
If it does then Steve Eddins answer seems to do the trick.
If, on the other hand, the object you are trying to segment is much smoother than the result I'd suggest one of two approaches.
If the target object is a cross (two lines), I'd probably calculate the lines and change the representation to two line segments. These can then be rendered at whatever precision and smoothness. To do this you could either find the center and rotation using some kind of feature detection algorithm, or you could use hough transforms to find the lines. The latter is probably much simpler.
If the target can have any form then I'd look into a better segmentation algorithm. There are segmentation algorithms that is not based on hard thresholds. I have used graph partitioning algorithms for this, and while slow, they work well.