我正在尝试使用相机测量一块陶瓷的尺寸变化
我正在尝试测量一块陶瓷在加热时尺寸的变化,我正在尝试使用相机和边缘检测来做到这一点。为了测试这一点,我首先使用从相机拍摄的图像(下图),并希望稍后过渡到实时视频源。
这是精明的图像,我理想地希望轮廓能够沿着陶瓷件的整个边缘,并且能够测量侧面的长度和面积。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.
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论