One of my friend was working on following project:
Below is the microscopic (SEM) image of the surface of stainless steel.
But you can see, it is corroded a little bit (after long exposure to marine environment) and some pits are formed on the surface. Some of the pits are marked in red circle.
He needs to find number of pits in the image and he was counting it manually (imagine, there are nearly 150 images). So I thought of automating this process with any image processing tool.
Question:
How can I find the number of pits in this image?
What I tried:
As a first step, I improved the contrast a little bit by closing operation.
import numpy as np
import cv2
from matplotlib import pyplot as plt
img = cv2.imread('6.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(11,11))
close = cv2.morphologyEx(gray, cv2.MORPH_CLOSE, kernel)
close2 = cv2.add(close,1)
div = (np.float32(gray)+1)/(close2)
div2 = cv2.normalize(div,None, 0,255, cv2.NORM_MINMAX)
div3 = np.uint8(div2)
Result:
Then I applied some threshold for 127 and find contours in it. Later these contours are filtered based on their area (there is no specific information on the area, I took a range of 1-10 as an empirical value).
ret, thresh = cv2.threshold(div3, 127,255, cv2.THRESH_BINARY_INV)
temp, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
res = np.zeros(gray.shape,np.uint8)
for cnt in contours:
if 1.0 < cv2.contourArea(cnt) < 10.0:
res = cv2.drawContours(res, [cnt], 0, 255, -1)
plt.subplot(121); plt.imshow(img, 'gray'); plt.subplot(122); plt.imshow(res,'gray'); plt.show()
But it ended up in a lot of extra noise. See the result below:
Additional Information:
Some test images: