Esettanulmány
A következőkben láthatjuk, hogy hogyan tudunk ténylegesen vizuális mérést végezni. A feladatban egy csavaranya belső átmérőjét fogjuk megmérni. A méréshez háttérvilágítást, telecentrikus optikát és ipari kamerát használunk. A képkészítést az ábrán látható elrendezésben hajtjuk végre (bal oldali kép), a középső kép a lefényképezett csavaranyát mutatja, a jobboldali képen egy referencia négyzet látható. Ügyelni kell a telecentrikus optika munkatávolságának beállítására!
A képfeldolgozás során a referencia négyzetből - melynek mérete ismert - meghatározzunk egy pixel-mm arányt. A csavaranya képet küszöböljük, meghatározzuk a csavaranya (külső és belső) kontúrját és a belső kontúrra kört illesztünk.
A pixel-mm arányának meghatározása:
- Konvertáljuk szürkeárnyalatossá a referencia négyzet képét.
- Küszöböljük a referencia négyzetet egy általunk választott küszöbértékkel (vagy pl. Otsu küszöböléssel)
- Számoljunk euklideszi távolságtérképet a szegmenált négyzetre, a legnagyobb távolságérték adja az oldalhossz felét.
- Mérjük le az oldalhosszt tolómérővel. Számoljuk ki az oldalhossz pixelben vett és mm-ben mért hosszának arányát.
A kör detektálása a csavaranya képen:
- Konvertáljuk a képet szürkeárnyalatossá!
- Küszöböljük a képet egy általunk választott küszöbértékkel vagy Otsu-féle küszöböléssel.
- Határozzuk meg a kontúrt a bináris képen (ezt morfológiai műveletekkel végezzük). Javítsuk a kontúrt dilatációval, hogy biztosabban detektáljuk a köröket.
- Detektáljunk köröket Hough transzformációval a kontúr képen.
- A megtalált körök közül választhatjuk az elsőt (a többi hasonló pozícióban és hasonló méretű lesz)
- Kérdezzük le a kör sugarát és használjuk a pixel-mm arányt a fizikai átmérő meghatározásához!
- Vessük össze a kapott értéket a fizikai mérettel!
import cv2
import numpy as np
import math
from matplotlib import pyplot as plt
## kép megnyitása
NUT_IMAGE = "../csavaranyaM5_telecentric_WD175mm.bmp"
REFERENCE_IMAGE = "../reference_sqaure_telecentric_WD175mm.bmp"
ref_img = cv2.imread(REFERENCE_IMAGE)
gray_ref_img = cv2.cvtColor(ref_img, cv2.COLOR_BGR2GRAY)
thresh_value, thresh_image = cv2.threshold(gray_ref_img, 127, 255, cv2.THRESH_OTSU);
print(thresh_value)
distmap = cv2.distanceTransform(thresh_image, cv2.DIST_L2, cv2.DIST_MASK_PRECISE)
distmax = np.amax(distmap)
print(distmax)
mm_to_pixel = 2*distmax / 20.0
## csavaranya kép feldolgozása
nut_img = cv2.imread(NUT_IMAGE)
gray_nut_img = cv2.cvtColor(nut_img, cv2.COLOR_BGR2GRAY)
thresh_value, thresh_nut = cv2.threshold(gray_nut_img, 220, 255, cv2.THRESH_BINARY);
se_3x3 = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3) )
eroded = cv2.erode(thresh_nut, se_3x3)
contour = cv2.bitwise_xor(thresh_nut, eroded)
dilated_contour = cv2.dilate(contour, se_3x3)
circles = cv2.HoughCircles(dilated_contour, cv2.HOUGH_GRADIENT, 2, gray_nut_img.shape[1])
circle = circles[0]
print(circle)
cv2.circle(nut_img, (circle[0,0], circle[0,1]), int(circle[0,2]), (255,0,0), 5)
computed_diameter = (2* circle[0,2] / mm_to_pixel)
print(computed_diameter)
plt.imshow(nut_img)
plt.show()