dvd
dvd

Reputation: 43

Finding the percentage of "cracks" in a SEM image

We have Scanning Electron Microscope (SEM) images of a certain cathode material and my aim is to find how much percentage of the image is occupied by cracks. Any suggestions on how this can be done? Currently I just try to find the number of "darkest" pixels in the image and take the percentage with the total number of pixels in the image. enter image description here

Here is my code so far:

ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required = True, help = "path to input image")
args = vars(ap.parse_args())

image = cv2.imread(args["image"])
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5,5), 0)
thresh = cv2.threshold(blurred, 0, 255, cv2.THRESH_BINARY)[1]
#imageCanny = cv2.Canny(blurred, 100, 200, 3)


#total number of pixels in the image = 1280x960 = 1228800
count = cv2.countNonZero(thresh)
img, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(image, contours, -1, (0,255,255), 2)
print(count)

If I do countNonZero(image) I get the error (-215) cn == 1 in function countNonZero, but not when I do countNonZero(thresh). Am I correctly finding the darkest pixels?

Upvotes: 3

Views: 506

Answers (1)

nathancy
nathancy

Reputation: 46680

If you define a "crack" as a dark pixel, then you can use np.where() to isolate cracks that are below some threshold. Essentially any pixel that is below this threshold will be defined as a crack. This will give you a grayscale image where you can use cv2.countNonZero() to determine the crack percentage. Using a threshold value of 30 (which can be adjusted in the range of [0..255]) here's the result:

enter image description here

Crack percentage: 16.74%

Code

import cv2
import numpy as np

# Load image as grayscale, change all pixels less than some threshold to black
image = cv2.imread('1.jpg', 0)
w,h = image.shape
image[np.where(image <= 30)] = 0

# Count non-crack pixels
pixels = cv2.countNonZero(image)

# Calculate crack percentage
percentage = 100 - (pixels / (w * h)) * 100
print('Crack percentage: {:.2f}%'.format(percentage))

cv2.imshow('image', image)
cv2.waitKey()

Upvotes: 2

Related Questions