Created
June 19, 2023 13:06
-
-
Save stefanherdy/ccdd19669684f9a85b64542e33a972aa to your computer and use it in GitHub Desktop.
This script iterates through a folder and performs an edge detection to all jpg and png-images in the folder. The function was used to monitor the additive manufacturing of steel and titanium parts (selective laser sintering). During the manufactoring process, the images were analysed and anomalies in the powder bed of the 3D printing machine we…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
""" | |
Script Name: python_edge_detection_for_quality_inspection.py | |
Author: Stefan Herdy | |
Date: 18.08.2019 | |
Description: | |
This script iterates through a folder and performs an edge detection to all jpg and png-images in the folder. | |
The provided function was used to monitor the additive manufacturing of steel and titanium parts (selective laser sintering). | |
During the manufactoring process, the images were analysed and anomalies in the powder bed of the 3D printing machine were detected. | |
Usage: | |
- Set your own function parameters for edge detection etc. | |
- Set your data path | |
- Import the script and execute the provided function | |
""" | |
from imutils import contours | |
from skimage import measure | |
import numpy as np | |
import argparse | |
import PIL | |
import imutils | |
import cv2 | |
from os import listdir | |
import sys | |
from PIL import Image | |
#from torchvision import transforms | |
#import torchvision | |
import shutil | |
import tkinter | |
import random | |
import os | |
import sqlite3 | |
import matplotlib.pyplot as plt | |
from tkinter.ttk import Progressbar | |
def detect_image_anomalies(path, low_thresh, high_thresh, area_thresh, g_size, cr_num): | |
if not os.path.exists(path): | |
tkinter.messagebox.showerror("Error", "Path does not exist!") | |
cfiles = listdir(path) | |
files = listdir(path) | |
if not files: | |
tkinter.messagebox.showerror("Error", "No files in the directory") | |
f = random.choice(cfiles) | |
# init arrays to store results of the egde detection | |
elist = [] | |
rlist = [] | |
rad = 0 | |
pro = 1 | |
text = " " | |
progressm = tkinter.Tk() | |
progressm.title("Progress") | |
progressl = tkinter.Label(progressm, text=text, width=25) | |
progress = Progressbar(progressm, orient="horizontal", length=100, mode='determinate') | |
images = [x for x in files if x.endswith(('jpg', 'png'))] | |
for img in images: | |
progressl["text"] = "Analysed:" + str(pro) + "of" + str(int(len(files))) | |
progressl.pack() | |
progress.pack() | |
progress['value'] = pro / (len(files)/2) * 100 | |
#fr1.update_idletasks() | |
progress.update_idletasks() | |
progressl.pack() | |
progressl.update_idletasks() | |
# load the image, convert it to grayscale, and blur it | |
dir = os.path.join(path, img) | |
image = cv2.imread(dir, 0) | |
# The Canny function does a blurr. Blurring the image first could still improve the quality of the analysis. | |
blurred = cv2.GaussianBlur(image, (g_size, g_size), 0) | |
# cv2.imshow("blurr", blurred) | |
canny = cv2.Canny(blurred, low_thresh, high_thresh) | |
## You can also perform erosion and dilation on your own: | |
# perform a series of erosions and dilations to remove | |
# any small blobs of noise from the thresholded image | |
kernel = np.ones((3, 3)) | |
# image = cv2.erode(image, kernel, iterations=1) | |
# image = cv2.dilate(image, None, iterations=4) | |
# perform a connected component analysis on the thresholded | |
# image, then initialize a mask to store only the "large" | |
# components | |
labels = measure.label(canny, neighbors=8, background=0) | |
mask = np.zeros(canny.shape, dtype="uint8") | |
# loop over the unique components | |
for label in np.unique(labels): | |
# if this is the background label, ignore it | |
if label == 0: | |
continue | |
# otherwise, construct the label mask and count the | |
# number of pixels | |
labelMask = np.zeros(canny.shape, dtype="uint8") | |
labelMask[labels == label] = 255 | |
numPixels = cv2.countNonZero(labelMask) | |
# if the number of pixels in the component is sufficiently | |
# large, then add it to our mask of "large blobs" | |
if numPixels > area_thresh: | |
mask = cv2.add(mask, labelMask) | |
# find the contours in the mask, then sort them from left to | |
# right | |
cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, | |
cv2.CHAIN_APPROX_SIMPLE) | |
cnts = imutils.grab_contours(cnts) | |
if cnts == True: | |
cnts = contours.sort_contours(cnts)[0] | |
rad = 0 | |
# loop over the contours | |
for (i, c) in enumerate(cnts): | |
# print(c) | |
maxlist = [] | |
# draw the bright spot on the image | |
(x1, y1, w1, h1) = cv2.boundingRect(c) | |
((cX, cY), radius) = cv2.minEnclosingCircle(c) | |
cv2.circle(image, (int(cX), int(cY)), int(radius), | |
(255, 255, 255), 1) | |
cv2.putText(image, "#{}".format(i + 1), (x1, y1 - 15), | |
cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 0, 255), 1) | |
maxlist.append(radius) | |
try: | |
rad = max(maxlist) | |
except: | |
rad = 0 | |
rlist.append(rad) | |
elist.append(len(cnts)) | |
# show the output image | |
name = str(img) | |
if len(cnts) > cr_num: | |
cv2.namedWindow(name) | |
cv2.moveWindow(name, 100, 100) | |
cv2.imshow(name, image) | |
cv2.waitKey(0) | |
cv2.destroyWindow(name) | |
pro +=1 | |
return elist | |
# set low and high threshold for Canny Edge detection | |
low_thresh = 75 | |
high_thresh = 180 | |
# Set threshold for the minimun area of the detected anomalies | |
area_thresh = 70 | |
# Spezify kernel size for gaussian blurr | |
g_size = 11 | |
# Set critical number of counts, where image is shown or not | |
cr_num = 0 | |
# Set data path | |
path = 'C:/Users/stefa/Pictures/Camera Roll/' | |
if __name__ == "__main__": | |
detect_image_anomalies(path, low_thresh, high_thresh, area_thresh, g_size, cr_num) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment