How do we remove illumination noise? - visual-c++

I have a car detecting project in OpenCV2.3.1 and visual C++.
In foreground segmentation, there's reflections due to illumination.
And this (reflections) become part of the foreground after the background
has been removed.
I need suggestions or ideas on how to remove this noise. As it causes some
foreground objects to be connected up as one object, like seen when using
findContours and drawContours functions. See image parts highlighted in red
on attached image. I think this will simplify the blob detection stage.
*note - I am not allowed to use built-in cvBlobLib in OpenCV

Issue here is that part of a glare can be either background or corresponding car.
Here is what I would do.
I believe you would not have a big problem with identifying glare parts by binarizing and thresholding or in a similar way.
Once identified all pixels of glares, I would replace each of the glare pixels with nearest non-glare pixel in the same row of the image. That way, a glare will be filled with car and background. With this method, then you would be able to detect cars without much problem.

maybe try to convert the image to HSV then filter high V amounts
IplImage imgHSV = cvCreateImage(cvGetSize(imgInput), 8, 3);
IplImage imgThreshold = cvCreateImage(cvGetSize(imgHSV), 8, 1);
cvInRangeS(imgHSV, cvScalar(0, 0, 90, 0), cvScalar(0, 0, 100, 0), imgThreshold);
..adjust scalars as needed to remove glare

Related

Smoothing the edges of segmented images

I am working on breast region segmentation using Huang Thresholding. The original and result image is provided here:
As you can see the mask edges are not smooth enough but it's accepted in this sample. Next is another sample with the mask edges pretty jagged:
In the attached picture I already implemented some preprocessing to smoothing the edge by using close operation with the following codes (I tried it with the median filter but not much effect).
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (15, 15))
closed = cv2.morphologyEx(canvas.copy(), cv2.MORPH_CLOSE, kernel, iterations=3)
I also tried the solution provided here:
but not satisfying enough for me in this case.
Can anybody help me or suggest me a method to smooth the edges of the mask? Here I have provided the mask images for sample1:
and for sample2:
.
FYI, I planned to bitwise_and the image with the mask so I can remove the background images. Background images in mammograms sometimes not really black background and contain too much noise which you don't want when enhancing the image after.
`

Process engraved text for OCR

I am working on these images to read the VIN number from the bottom of the car.
Before i proceed with the OCR, i am trying to process the images some how.
image = cv2.imread(imgpath)
# Convert To gray scale
imagegray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Edge Detection since it is engraved
high_thresh, thresh_im = cv2.threshold(imagegray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
low_thresh = 0.5*high_thresh
imagecanny = cv2.Canny(imagegray, low_thresh, high_thresh)
# Dilation
kernel = np.ones((2,2),np.uint8)
imagedilated = cv2.dilate(imagecanny, kernel, iterations = 1)
kernel = np.ones((2,2),np.uint8)
imageeroded = cv2.erode(imagedilated, kernel, iterations = 1)
And this is what i have so far.
There are additional challenges in the images that i have, such as:-
Not all the images are having horizontal orientation -- Skew is present. Any idea how can i fix that?
Some engravings are deep while some are shallow, How can deal with that?
Assume that these images were being taken from a photo camera.
I am bit of a newbie in this field. Any help would be appreciated.Thanks
I don't deal with graphics but perhaps I can say at least something. I downloaded your pics and tried to adjust the colors in your image manually in my favourite photo editor. To make the text even, I applied grayscale and played with Gamma correction and Contrast. It gave me nothing until I cropped the images to a narrow strip, like this:
After this, adjustments work much better. Therefore my advice would be to require as little graphic data as possible to avoid such interference. And you will probably want to check out some fonts that are used by various manufacturers, since here I can see different fonts. If there's not much choice, you can generate those fonts for yourself.

Otsu's method thresholding making a 'shroud'

I'm trying to threshold an image using Otsu's method in Opencv:
Although when I threshold it, some parts of the picture are completely surrounded by white and creates and ends up in Opencv not detecting all the contours in the image. This is what I get when I do Otsu's method thresholding usingret,thresh=cv2.threshold(blurred,0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU):
EDIT:
Some people have asked for the code I am using so here it is:
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
cv2.imshow('Input Image', image)
cv2.waitKey(0)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
thresh = cv2.adaptiveThreshold(blurred,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,\
cv2.THRESH_BINARY_INV,81,2)
#ret, thresh = cv2.threshold(blurred,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
kernel = np.ones((5,5),np.uint8)
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
closing = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
#thresh_value = 70
#ret,thresh= cv2.threshold(blurred,thresh_value,255,cv2.THRESH_BINARY)
Now it makes some checkered noise:
You do not need to manually find a sweet spot! Let OpenCV do it for you!
OpenCV has an adaptive thresholding algorithm exactly from problems like this, called adaptiveThreshold
This function divides the image into multiple sub-images, and thresholds each one individually. This means that it will find a nice threshold value for each part of the image and give you a nice and uniformly lit image. See this example.
Try this:
th3 = cv.adaptiveThreshold(blurred,255,cv.ADAPTIVE_THRESH_GAUSSIAN_C,\
cv.THRESH_BINARY,11,2)
Update:
Functions like these do not work perfectly out of the box. If it still creates artefacts like salt and pepper noise, you can try:
Significantly increasing the blockSize. This can ensure that each block has a letter inside, which will hopefully mean the threshold will be chosen better. (e.g. Dividing the image into 25 blocks instead of 100. A blocksize of 11 pixels is very small.)
First apply a blurring filter to ease out the bad spots creating the seasoning noise. (With the image name blurry I imagine that you've done this already.
First the simple threshold function to just removes some noise. For example setting all pixels above 5 and below 100 equal to zero. Then after that apply the adaptiveThreshold.
Follow #Mark`s advice by subtracting a blurred image from the original image. (See this thread)
I hope this helps!
Instead of using Otsu's method try global thresholding method.
thresh_value = 50
ret,thresh= cv2.threshold(blurred,thresh_value,255,cv2.THRESH_BINARY)
change the thresh_value parameter until you get the result you want.
Get to know more about thresholding techniques please refer the documentation.

Reducing / Enhancing known features in an image

I am microbiology student new to computer vision, so any help will be extremely appreciated.
This question involves microscope images that I am trying to analyze. The goal I am trying to accomplish is to count bacteria in an image but I need to pre-process the image first to enhance any bacteria that are not fluorescing very brightly. I have thought about using several different techniques like enhancing the contrast or sharpening the image but it isn't exactly what I need.
I want to reduce the noise(black spaces) to 0's on the RBG scale and enhance the green spaces. I originally was writing a for loop in OpenCV with threshold limits to change each pixel but I know that there is a better way.
Here is an example that I did in photo shop of the original image vs what I want.
Original Image and enhanced Image.
I need to learn to do this in a python environment so that I can automate this process. As I said I am new but I am familiar with python's OpenCV, mahotas, numpy etc. so I am not exactly attached to a particular package. I am also very new to these techniques so I am open to even if you just point me in the right direction.
Thanks!
You can have a look at histogram equalization. This would emphasize the green and reduce the black range. There is an OpenCV tutorial here. Afterwards you can experiment with different thresholding mechanisms that best yields the bacteria.
Use TensorFlow:
create your own dataset with images of bacteria and their positions stored in accompanying text files (the bigger the dataset the better).
Create a positive and negative set of images
update default TensorFlow example with your images
make sure you have a bunch of convolution layers.
train and test.
TensorFlow is perfect for such tasks and you don't need to worry about different intensity levels.
I initially tried histogram equalization but did not get the desired results. So I used adaptive threshold using the mean filter:
th = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 3, 2)
Then I applied the median filter:
median = cv2.medianBlur(th, 5)
Finally I applied morphological closing with the ellipse kernel:
k1 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
dilate = cv2.morphologyEx(median, cv2.MORPH_CLOSE, k1, 3)
THIS PAGE will help you modify this result however you want.

Alpha Blending to remove seam in an image

I have stitched two images but in the final image there is a visible seam. I am trying to use Alpha blending to remove that seam. I know Alpha blending is applied using the cvAddweight() function, but in this the function parameters are two images,alpha, beta , gamma and desitination . I am taking gamma=0, alpha=0.6, beta=0.4. What will be my two input source images and the destination image as the last part of my code is this->
IplImage* WarpImg = cvCreateImage
(cvSize(T1Img->width*2, T1Img->height*2), T1Img->depth, T1Img- >nChannels);
cvWarpPerspective(T1Img, WarpImg, &mxH);
cvSetImageROI(WarpImg, cvRect(0, 0, T2Img->width, T2Img->height));
cvCopy(T2Img, WarpImg);
cvResetImageROI(WarpImg);
cvNamedWindow("WarpImg Img",1);
cvShowImage("WarpImg Img", WarpImg);
cvSaveImage("save.jpg",WarpImg);
My final Image is
I have to admit, I dont think alpha blending is your answer. The seem is there due to the difference in lighting / exposure. Alpha blending is a way of essentially having one image visible through another by means of weighted averaging the two images colors together. Your right and your left images are backed by black. If you simply alpha blend then you are essentially going to be weighting your images with a black background. The resultant effect will simply be a darkening of both images.
2 potential other methods might be to look at the average color of both images at the seem, and adjust one up or down by 50% of the difference in brightness, and the other opposite by the other 50% (one goes up and the other down and the 50% makes it so that the overall brightness jump by either is only 50% of the difference).
The other might do a more complex image histogram technique where you try to widen or shrink the histogram of one side' image to the other as well as align them, and re-asign your color (in this case grayscale) via the new histograms.
Pyramid/multiband blending should do a good enough job for you scenario. Try enblend: http://enblend.sourceforge.net

Resources