thresholding an image based on gradient - matlab

I have multiple simple circle objects in grid of an image from which I want to create mask image for the objects. A gotcha is that light intensity for each object is different. So simple thresholding would not create a mask.
As a solution, I want to threshold based on gradient. Basically, I'd like to first find the circle with edge detection and make inside of the circle white and outside black. But this is really slow. Is there any better way to do this on matlab?

I would create a low-pass filtered version of the image, and use it as the threshold. The "strength" of the filter should be tuned carefully in order to make the result follow the distribution of light intensity, but this is not that hard.
(This approach worked for me when I had to extract the contour of blood vessels from brain-surface images, few years ago.)

Related

Headlights detection using Difference of Gaussian (DoG)

I am developing a project of detecting vehicles' headlights in night scene. First I am working on a demo on MATLAB. My detection method is edge detection using Difference of Gaussian (DoG): I take the convolution of the image with Gaussian blur with 2 difference sigma then minus 2 filtered images to find edge. My result is shown below:
Now my problem is to find a method in MATLAB to circle the round edge such as car's headlights and even street lights and ignore other edge. If you guys got any suggestion, please tell me.
I think you may be able to get a better segmentation using a slightly different approach.
There is already strong contrast between the lights and the background, so you can take advantage of this to segment out the bright spots using a simple threshold, then you can apply some blob detection to filter out any small blobs (e.g. streetlights). Then you can proceed from there with contour detection, Hough circles, etc. until you find the objects of interest.
As an example, I took your source image and did the following:
Convert to 8-bit greyscale
Apply Gaussian blur
Threshold
This is a section of the source image:
And this is the thresholded overlay:
Perhaps this type of approach is worth exploring further. Please comment to let me know what you think.

how to segment sky & water part in a picture

I'm trying to segment the sky and water part in this image.
Link of the Picture
I've tried so many methods like k-means, threshold, multi threshold etc. BUt unfortunately nothing worked so well.
Here is an example of my code(Matlab):
img=imread('1.jpg');
im_gray=rgb2gray(img);
b=imadjust(im_gray);
imshow(b);
bw_remove_small=imopen(b,strel('square',5));
imshow(bw_remove_small); %after 1st iteration
m3=medfilt2(bw_remove_small,[18,16]);
imshow(m3);
m3=medfilt2(bw_remove_small,20,20]);
m3=medfilt2(bw_remove_small,[20,20]);
imshow(m3);
I1=m3;
I2=rgb2gray(I1);
I=double(I2);
figure
subplot(1,3,1)
imshow(I1)
subplot(1,3,2)
imshow(I2)
g=kmeans(I(:),4);
J = reshape(g,size(I));
subplot(1,3,3)
imshow(J,[]);
Can any one help me?please
The picture's two regions are different in hue, texture, and gray level brightness.
The horizon is the best line in the image from our point of view and can be seen by the distinct change in brightness. The brightness will not work with a single threshold because the image brightness is not flat, so use brightness a model of the distribution to flatten out the sky or the water. This implies knowledge of the objective but there are two things that can give you an approximate answer: texture and/or hue.
The hue with a threshold of 120 (derived from the hue histogram) will give you the two regions but will not be divided cleanly and will have overlapping sections. Though using these two sections a model of the brightness can be found.
The same with texture. Using a small fft of the image, subtracting the dc out, then averaging or just summing up the non dc parts will result in a histogram with two peaks that may not be as distinct as the hue's is but is enough to find a threshold and two areas that will allow a model of the brightness to be found.
The key fact is if the sky is modeled properly as a gray surface then you can subtract it out of the image and use a simple threshold to pull it out.
Edge detection is very noisy in this image to be able to easily see the line but if you can pull out the image lines without losing shape then look for a straight and long contour it may take less code/work.
Hope this helps some! I used this to find mountains in the distance when there was not a big difference between the sky and the mountains. Plus I just tried this on your pic and almost got a good answer without a good model of the sky.

Filter Noise in MatLab

Hi I'm attempting to filter an image with 4 objects inside using MatLab. My first image had a black background with white objects so it was clear to me to filter each image out by finding these large white sections using BW Label and separating them from the image.
The next image has noise in it though. Now I have an image with white lines running through my objects and they are actually connected to each other now. How could I filter out these lines in MatLab? What about Salt and pepper noise? Are there MatLab functions that can do this?
Filtering noise can be done in several ways. A typical noise filtering procedure will be something like threshold>median filtering>blurring>threshold. However, information regarding the type of noise can be very important for proper noise filtration. For examples, since you have lines in your image you can try to use a Hough transform to detect them and take them out of the play (or houghlines). Another approach can be to implement RANSAC. For salt & pepper type of noise, one should use medfilt2 with a proper window size that captures the noise characteristics (for example 3x3 window will deal well with noise fluctuations that are 1 pixel big...).
If you can live with distorting the objects a bit, you can use a closing (morphological) filter with a bit of contrast stretching. You'll need the image processing toolbox, but here's the general idea.
Blur to kill the lines otherwise the closing filter will erase your objects. You can use fspecial to create a Gaussian filter and imfilter to apply it
Apply the closing filter to the image using imclose with a mask that's bigger then your noise, but smaller then the object pieces (I used a 3x3 diamond in my example).
Threshold your image using im2bw so that every pixel gets turned to pure black or pure white based
I've attached an example I had to do for a school project. In my case, the background was white and objects black and I stretched between the erosion and dilation. You can't really see the gray after the erosion, but it was there (hence the necessity for thresholding).
You can of course directly do the closing (erosion followed by dilation) and then threshold. Notice how this filtering distorts the objects.
FYI usually salt-and-pepper noise is cleaned up with a moving average filter, but that will leave the image grayscale. For my project, I needed a pure black and white (for BW Label) and the morphological filters worked great to completely obliterate the noise.

Segmenting 3D shapes out of thick "lines"

I am looking for a method that looks for shapes in 3D image in matlab. I don't have a real 3D sample image right now; in fact, my 3D image is actually a set of quantized 2D images.
The figure below is what I am trying to accomplish:
Although the example figure above is a 2D image, please understand that I am trying to do this in 3D. The input shape has these "tentacles", and I have to look for irregular shapes among them. The size of the tentacle from one point to another can change around but at "consistent and smooth" pace - that is it can be big at first, then gradually smaller later. But if suddenly, the shape just gets bigger not so gradually, like the red bottom right area in the figure above, then this is one of the volume of interests. Note that these shapes have more tendency to be rounded and spherical, but some of them are completely arbitrary and random.
I've tried the following methods so far:
Erode n times and dilate n times: given that the "tentacles" are always smaller than the volume of interest, this method will work as long as the volume is not too small. And, we need to have a mechanism to deal with thicker portion of the tentacle that becomes false positive somehow.
Hough Transform: although I have been suggested this method earlier (from Segmenting circle-like shapes out of Binary Image), I see that it works for some of the more rounded shape cases, but at the same time, more difficult cases such that of less-rounded, distorted, and/or arbitrary shapes can slip through this method.
Isosurface: because of my input is a set of 2D quantized images, using an isosurface allow me to reconstruct image in 3D and see things clearer. However, I'm not sure what could be done further in this case.
So can anyone suggests some other techniques for segmenting such shape out of these "tentacles"?
Every point on your image has the property that it is either part of the tentacle, or part of the volume of interest. If it is unknown apriori what the expected girth of the tentacle is, then 1 wont work because we won't be able to set n. However, we know that the n that erases the tentacle is smaller than the n that erases the node. You can for each point replace it with an integer representing the distance to the edge. Effectively, this can be done via successive single pixel erosion, and replacing each pixel with the count of the iteration at which it was erased. Lets call this the thickness at the pixel, but my rusty old mind tells me that there was a term of art for this.
Now we want to search for regions that have a higher-than-typical morphological distance from the boundary. I would do this by first skeletonizing the image (http://www.mathworks.com/help/toolbox/images/ref/bwmorph.html) and then searching for local maxima of the thickness along the skeleton. These are points on the skeleton where the thickness is larger than the neighbor points.
Finally I would sort the local maxima by the thickness, a threshold on which should help to separate the volumes of interest from the false positives.

Remove paper texture pattern from a photograph

I've scanned an old photo with paper texture pattern and I would like to remove the texture as much as possible without lowering the image quality. Is there a way, probably using Image Processing toolbox in MATLAB?
I've tried to apply FFT transformation (using Photoshop plugin), but I couldn't find any clear white spots to be paint over. Probably the pattern is not so regular for this method?
You can see the sample below. If you need the full image I can upload it somewhere.
Unfortunately, you're pretty much stuck in the spatial domain, as the pattern isn't really repetitive enough for Fourier analysis to be of use.
As #Jonas and #michid have pointed out, filtering will help you with a problem like this. With filtering, you face a trade-off between the amount of detail you want to keep and the amount of noise (or unwanted image components) you want to remove. For example, the median filter used by #Jonas removes the paper texture completely (even the round scratch near the bottom edge of the image) but it also removes all texture within the eyes, hair, face and background (although we don't really care about the background so much, it's the foreground that matters). You'll also see a slight decrease in image contrast, which is usually undesirable. This gives the image an artificial look.
Here's how I would handle this problem:
Detect the paper texture pattern:
Apply Gaussian blur to the image (use a large kernel to make sure that all the paper texture information is destroyed
Calculate the image difference between the blurred and original images
EDIT 2 Apply Gaussian blur to the difference image (use a small 3x3 kernel)
Threshold the above pattern using an empirically-determined threshold. This yields a binary image that can be used as a mask.
Use median filtering (as mentioned by #Jonas) to replace only the parts of the image that correspond to the paper pattern.
Paper texture pattern (before thresholding):
You want as little actual image information to be present in the above image. You'll see that you can very faintly make out the edge of the face (this isn't good, but it's the best I have time for). You also want this paper texture image to be as even as possible (so that thresholding gives equal results across the image). Again, the right hand side of the image above is slightly darker, meaning that thresholding it well will be difficult.
Final image:
The result isn't perfect, but it has completely removed the highly-visible paper texture pattern while preserving more high-frequency content than the simpler filtering approaches.
EDIT
The filled-in areas are typically plain-colored and thus stand out a bit if you look at the image very closely. You could also try adding some low-strength zero-mean Gaussian noise to the filled-in areas to make them look more realistic. You'd have to pick the noise variance to match the background. Determining it empirically may be good enough.
Here's the processed image with the noise added:
Note that the parts where the paper pattern was removed are more difficult to see because the added Gaussian noise is masking them. I used the same Gaussian distribution for the entire image but if you want to be more sophisticated you can use different distributions for the face, background, etc.
A median filter can help you a bit:
img = imread('http://i.stack.imgur.com/JzJMS.jpg');
%# convert rgb to grayscale
img = rgb2gray(img);
%# apply median filter
fimg = medfilt2(img,[15 15]);
%# show
imshow(fimg,[])
Note that you may want to pad the image first to avoid edge effects.
EDIT: A smaller filter kernel than [15 15] will preserve image texture better, but will leave more visible traces of the filtering.
Well i have tried out a different approach using Anisotropc diffusion using the 2nd coefficient that operates on wider areas
Here is the output i got:
From what i can See from the Picture, the Noise has a relatively high Frequency Compared to the image itself. So applying a low Pass filter should work. Have a look at the Power spectrum abs(fft(...)) to determine the cutoff Frequency.