Detect a scratch on noise image with OpenCV - python

I am trying to get a small scratch from the noise image as shown. It is quite noticeable by eyes, but I would like to identify it using OpenCV Python.
I tried to use image blurring and subtract it from the original image, and then threshold to get a image as the second.
Could any body please advise to get this scratch?
Original image:
Image after blurring, subtraction, and threshold:
This is how I process this image:
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread("scratch0.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blur = cv2.blur(gray,(71,71))
diff = cv2.subtract(blur, gray)
ret, th = cv2.threshold(diff, 13, 255, cv2.THRESH_BINARY_INV)
cv2.imshow("threshold", th)
cv2.waitKey(0)

Related

Seeds segmentation in OpenCV/Python

I know that this topic has been covered before but I'm stuck.
I'm quite new and I trying to segment a seeds using Python and OpenCV
Here is my steps
And now I'm stuck on how to separate the 3 seeds in the center of the image. Then I use the distance transformation, but the result is not satisfactory (why it is hardly visible?). I don't know how to proceed further. I would like to achive something like this.
Distance transform
In more circular object dt works well but not in my case.
My code:
import cv2
from google.colab.patches import cv2_imshow
import numpy as np
img = cv2.imread('connected_seeds.jpg')
img = cv2.resize(img,(600,400))
# Gray scale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Blur image
blur_img = cv2.medianBlur(gray, 7)
# Thresholding
ret, thresh = cv2.threshold(blur_img, 0, 255, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
# Closing
kernel = np.ones((5,5), np.uint8)
closing = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=2)
sure_bg = cv2.dilate(closing,kernel,iterations=2)
# Distance transform
dist_transform = cv2.distanceTransform(closing, cv2.DIST_L2, 5)
ret, sure_fg = cv2.threshold(dist_transform,0.5*dist_transform.max(),255,0)
here is the article I'm following:
https://learning.rc.virginia.edu/notes/opencv/

How to Enhance Image contrast and brightness

I have a input image and i want to improve contrast and brightness
input image:
After run my code result is:
But finally image i want(Clarity filter in Windows 10 Photos app in edit mode you can use this link for more details https://www.digitalunite.com/technology-guides/digital-photography/editing-photos-and-videos-windows-10-using-photos-app):
(more details and better separation of objects and color)
My code is:
import cv2
import numpy as np
import skimage.filters as filters
from PIL import ImageFilter,ImageEnhance
# read the image
img = cv2.imread('input.png')
# convert to gray
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# blur
smooth = cv2.GaussianBlur(gray, (95,95),0)
# divide gray by morphology image
division = cv2.divide(gray, smooth, scale=40)
# sharpen using unsharp masking
result = filters.unsharp_mask(division, radius=2.5, amount=1, multichannel=False, preserve_range=False)
result = (220*result).clip(0,220).astype(np.uint8)
cv2.imshow('smooth', result)
cv2.waitKey(0)
cv2.destroyAllWindows()

Generation of skeleton from fiber image

I am new to image processing. I am doing image processing of fiber image to generate skeleton using morphology function from skimage. The generated skeleton shows lots of small unnecessary loops/circles around it. I need a single medial axis line (skeleton) for each fiber in image. I have used following code to generate skeleton. Also, attached original and skeleton image for reference. Can someone help in to improve the skeleton generation step?
[import cv2
import numpy as np
from skimage import morphology
img = cv2.imread('img.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# dilate and threshold
kernel = np.ones((2, 2), np.uint8)
dilated = cv2.dilate(gray, kernel, iterations=1)
ret, thresh = cv2.threshold(dilated, 215, 255, cv2.THRESH_BINARY_INV)
cv2.imwrite('Binary.jpg',thresh)
# skeletonize
skeleton = morphology.skeletonize(thresh, method='lee')
skeleton = morphology.remove_small_objects(skeleton.astype(bool), 100, connectivity=2)
cv2.imwrite('Skeleton.jpg',skeleton*255)]
I'm not seeing the skeleton. Here's what I was able to come up with binary thresholding + morphological operations + small object clean up:
from skimage.morphology import binary_opening, binary_closing, thin, disk, remove_small_objects, remove_small_holes
from skimage.filters import threshold_otsu
from skimage.color import rgb2gray
import numpy as np
img_gray = rgb2gray(img) # image was rgb for me
mask = img_gray < threshold_otsu(img_gray) + 15/255
mask = binary_opening(binary_closing(mask, disk(2)), disk(2))
mask = remove_small_objects(mask, 300)
mask = remove_small_holes(mask, 300)
skeleton = thin(mask)
plot(skeleton)
You can probably play around with the kernel shape for the opening/closing, as well as use individual erosion/dilation operations, to get a stronger output. You may also try different skeletonizing techniques, as I know different ones produce varying results.

Detection and segmentation of region of interest from X-ray images

I am working on some Xray images and I want to detect and segment region of interest from the image.
Consider input image
I want to detect square like shapes in the image, as highlighted in the image
Output: region of interest will somehow look like this
This is my code which I have done so far
import cv2
import numpy as np
import pandas as pd
import os
from PIL import Image
import matplotlib.pyplot as plt
from skimage.io import imread, imshow
img = cv2.imread('image.jpg',0)
imshow(img)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
imshow(gray)
equ = cv2.equalizeHist(img)
imshow(equ)
img_resize = cv2.resize(img, (300, 300))
print(img_resize.shape)
figure_size = 9
new_image_gauss = cv2.GaussianBlur(img_resize, (figure_size, figure_size),0)
imshow(new_image_gauss)
img_edge = cv2.Canny(equ,100,200)
# show the image edges on the newly created image window
imshow(img_edge)
kernel = np.ones((5,5), np.uint8)
img_erosion = cv2.erode(img_edge, kernel, iterations=1)
img_dilation = cv2.dilate(img_edge, kernel, iterations=1)
imshow(img_erosion)
Results which I have got;
Please guide me.
TIA
One thing that might help is to do morphology gradient on your image to emphasize the edges in Python OpenCV before you do your Canny edge detection.
Input:
import cv2
import numpy as np
# read image
img = cv2.imread("xray2.jpg")
# convert img to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# do morphology gradient
kernel = cv2.getStructuringElement(cv2.MORPH_RECT , (3,3))
morph = cv2.morphologyEx(gray, cv2.MORPH_GRADIENT, kernel)
# apply gain
morph = cv2.multiply(morph, 5)
# write results
cv2.imwrite("xray2_gradient_edges.jpg",morph)
# show lines
cv2.imshow("morph", morph)
cv2.waitKey(0)

how to detect irregular circles in python with opencv

I want to create a vision system for the detection of defect in SMD capacitors, the defect is called "pinhole" and they are small holes in the surface of the chip that are generated at the time of construction. my objective is to create an algorithm that is able of detecting these holes and with this, discard the chips that have this defect
For the moment I have created two codes:
the first one converts the original image to a binary image so that I can clear the circles, the code and the result is as follows. after obtaining the image in a binary way, I don't know how to make my algorithm detect that there is a circle, according to what I have investigated with "HOUGH" it can only be applied to images in grayscale
`
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread("C:/Users/Johanna Menendez/Documents/UNIR/TFM/chips/20190905_124734.jpg", 0)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
newImg = cv2.resize(img, (0,0), fx=0.50, fy=0.50)
(thresh, blackAndWhiteImage) = cv2.threshold(newImg, 127, 255, cv2.THRESH_BINARY)
numpy_vertical_concat = np.concatenate((newImg, blackAndWhiteImage), axis=1)
cv2.imshow('binary', numpy_vertical_concat)
cv2.waitKey(0)
`
binary
-The second is with contours detection, the problem with this is that it not only detects circles and likewise after this I don't know how to make my algorithm detect that it is a circle
import cv2
`
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread("C:/Users/Johanna Menendez/Documents/UNIR/TFM/chips/20190905_124734.jpg", 0)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
newImg = cv2.resize(img, (0,0), fx=0.50, fy=0.50)
gray = cv2.cvtColor(newImg, cv2.COLOR_RGB2GRAY)
(thresh, blackAndWhiteImage) = cv2.threshold(gray, 130, 255, cv2.THRESH_BINARY)
(contours, hierarchy) = cv2.findContours(blackAndWhiteImage, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
img = cv2.drawContours(newImg, contours, -1, (0, 255, 0), 2)
#numpy_vertical_concat = np.concatenate((newImg, img), axis=1)
cv2.imshow('binary', img)
cv2.waitKey(0)`
contours detection
could help me find out how to know the way for my algorithm to detect the circles please?

Categories