我正在尝试使用相机测量一块陶瓷的尺寸变化

发布于 2025-01-16 22:09:50 字数 3610 浏览 1 评论 0原文

我正在尝试测量一块陶瓷在加热时尺寸的变化,我正在尝试使用相机和边缘检测来做到这一点。为了测试这一点,我首先使用从相机拍摄的图像(下图),并希望稍后过渡到实时视频源。

这是精明的图像,我理想地希望轮廓能够沿着陶瓷件的整个边缘,并且能够测量侧面的长度和面积。canny image

我一直在使用 canny 和其他一些图像处理算法来定义边缘,然后这些将是使用查找并抓取轮廓,然后使用边界框来测量尺寸(以像素为单位)来循环这些轮廓,但这被证明是很困难的。我对此完全陌生,并且主要使用教程,下面的代码显示了我一直在尝试的一些图像预处理。有更好的方法吗?你能在没有边界框的情况下测量轮廓的长度吗?

任何帮助表示赞赏。

图像预处理

img = cv2.imread('buller_ring_test.jpg') 
imgCanny = cv2.Canny(img, 110, 255)
#imggrey = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 
#imgThre = cv2.adaptiveThreshold(imggrey, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2) 
#imgBlur = cv2.GaussianBlur(img, (5, 5), 1) imgCanny = cv2.Canny(img, 110, 255) plt.figure(figsize = (15,15)) plt.imshow(imgCanny)

循环轮廓

#find the total contours
conts = cv2.findContours(imgThre,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
#fine tune contours
conts = imutils.grab_contours(conts)
print (len(conts))

#create empty image with original dimensions
conts_img = np.zeros(img.shape)
plt.imshow(conts_img)

#draw contours onto the rmpty image to isolate contours
conts_img = cv2.drawContours(conts_img, conts, -1, (0,255,0), 2)
plt.figure(figsize = (15,15))
plt.imshow(conts_img)

#draw contours onto the rmpty image to isolate contours
#create the empty image with original dimensions
conts_img = np.zeros(img.shape)

def midPoint(ptA, ptB):
    return ((ptA[0] + ptB[0])/2, (ptA[1] + ptB[1])/2)



#loop over all the contours coordinates
for c in conts:
    #extract box points
    box = cv2.minAreaRect(c)
    box = cv2.boxPoints(box)
    #convert the box points into integer
    box = np.array(box, dtype = int)
    #print(box)
    
    if cv2.contourArea(c) < 10: #anything above this number gets used
        continue

    #draw the contour c (it will loop over all individual c's to make conts_img)
    cv2.drawContours(conts_img, [c], -1, (0,255,0), 2)
    cv2.drawContours(conts_img, [box], -1, (255,255,255), 2)

    print(box)
    for (x,y) in box:
        cv2.circle(conts_img, (x, y), 2, (255, 0, 0), 1)
        print(x,y)
        (tl, tr, br, bl) = box
        
        #calcualte midPoints for top & bottom
        (tlX, trX) = midPoint(tl, tr)
        (brX, blX) = midPoint(bl, br)
        #draw midPoint dots for top & bottom
        cv2.circle(conts_img, (int(tlX), int(trX)), 1, (255, 0, 0), 2)
        cv2.circle(conts_img, (int(brX), int(blX)), 1, (255, 0, 0), 2)
        #calculate the distance based on the midPoints
        dA = dist.euclidean((tlX, trX), (brX, blX)) #width
        #print the size in px on each contour rectangle
        cv2.putText(conts_img, '{:.1f} px'.format(dA), (int(tlX)-40, int(trX)-40),
         cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 1)
        
        #calcualte midPoints for left & right
        (tlX, trX) = midPoint(tl, bl)
        (brX, blX) = midPoint(tr, br)
        #draw midPoint dots for left & right
        cv2.circle(conts_img, (int(tlX), int(trX)), 1, (255, 0, 0), 2)
        cv2.circle(conts_img, (int(brX), int(blX)), 1, (255, 0, 0), 2)
        #calculate the distance based on the midPoints
        dB = dist.euclidean((tlX, trX), (brX, blX)) #height
        #print the size in px on each contour rectangle
        cv2.putText(conts_img, '{:.1f} px'.format(dB), (int(brX)-40, int(blX)-40),
         cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 1)
        



#show the processed image with the contours printed
plt.figure(figsize = (15,15))
plt.imshow(conts_img)
plt.show()

I am trying to measure the change in size a piece of ceramic as it is heated, I am attempting to do this using a camera and edge detection. To test this I am firstly using an image taken from the camera (image below) and hopefully transitioning to a live video feed later.ceramic at room temp

Here is the canny image, I would ideally like to get the contours to follow the entire edge of the ceramic piece and be able to measure the length of the sides and the area.canny image

I have been using canny and some other image processing algorithms to define the edges, these will then be using to find and grab contours to then loop over these using a bounding box to measure the size (in pixels), but this is proving to be difficult. I am completely new to this and have been using mainly tutorials, the code below shows some of the image preprocessing I have been attempting. Is there a better way of doing this? can you measure the length of contours without a bounding box?

Any help is appreciated.

Image preprocessing

img = cv2.imread('buller_ring_test.jpg') 
imgCanny = cv2.Canny(img, 110, 255)
#imggrey = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 
#imgThre = cv2.adaptiveThreshold(imggrey, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2) 
#imgBlur = cv2.GaussianBlur(img, (5, 5), 1) imgCanny = cv2.Canny(img, 110, 255) plt.figure(figsize = (15,15)) plt.imshow(imgCanny)

Looping over contours

#find the total contours
conts = cv2.findContours(imgThre,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
#fine tune contours
conts = imutils.grab_contours(conts)
print (len(conts))

#create empty image with original dimensions
conts_img = np.zeros(img.shape)
plt.imshow(conts_img)

#draw contours onto the rmpty image to isolate contours
conts_img = cv2.drawContours(conts_img, conts, -1, (0,255,0), 2)
plt.figure(figsize = (15,15))
plt.imshow(conts_img)

#draw contours onto the rmpty image to isolate contours
#create the empty image with original dimensions
conts_img = np.zeros(img.shape)

def midPoint(ptA, ptB):
    return ((ptA[0] + ptB[0])/2, (ptA[1] + ptB[1])/2)



#loop over all the contours coordinates
for c in conts:
    #extract box points
    box = cv2.minAreaRect(c)
    box = cv2.boxPoints(box)
    #convert the box points into integer
    box = np.array(box, dtype = int)
    #print(box)
    
    if cv2.contourArea(c) < 10: #anything above this number gets used
        continue

    #draw the contour c (it will loop over all individual c's to make conts_img)
    cv2.drawContours(conts_img, [c], -1, (0,255,0), 2)
    cv2.drawContours(conts_img, [box], -1, (255,255,255), 2)

    print(box)
    for (x,y) in box:
        cv2.circle(conts_img, (x, y), 2, (255, 0, 0), 1)
        print(x,y)
        (tl, tr, br, bl) = box
        
        #calcualte midPoints for top & bottom
        (tlX, trX) = midPoint(tl, tr)
        (brX, blX) = midPoint(bl, br)
        #draw midPoint dots for top & bottom
        cv2.circle(conts_img, (int(tlX), int(trX)), 1, (255, 0, 0), 2)
        cv2.circle(conts_img, (int(brX), int(blX)), 1, (255, 0, 0), 2)
        #calculate the distance based on the midPoints
        dA = dist.euclidean((tlX, trX), (brX, blX)) #width
        #print the size in px on each contour rectangle
        cv2.putText(conts_img, '{:.1f} px'.format(dA), (int(tlX)-40, int(trX)-40),
         cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 1)
        
        #calcualte midPoints for left & right
        (tlX, trX) = midPoint(tl, bl)
        (brX, blX) = midPoint(tr, br)
        #draw midPoint dots for left & right
        cv2.circle(conts_img, (int(tlX), int(trX)), 1, (255, 0, 0), 2)
        cv2.circle(conts_img, (int(brX), int(blX)), 1, (255, 0, 0), 2)
        #calculate the distance based on the midPoints
        dB = dist.euclidean((tlX, trX), (brX, blX)) #height
        #print the size in px on each contour rectangle
        cv2.putText(conts_img, '{:.1f} px'.format(dB), (int(brX)-40, int(blX)-40),
         cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 1)
        



#show the processed image with the contours printed
plt.figure(figsize = (15,15))
plt.imshow(conts_img)
plt.show()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文