OpenCV Python對象測量

一、效果

在這裏插入圖片描述

OpenCv版本4.0.0

Python版本3.7.2

編譯環境: PyCharm

二、代碼

import cv2 as cv
import numpy as np
from scipy.spatial import distance as dist
# 定義中點座標運算
def midpoint(ptA, ptB):
    return ((ptA[0] + ptB[0]) * 0.5, (ptA[1] + ptB[1]) * 0.5)
def measure(img):
    # 轉灰度
	gray = cv.cvtColor(img, cv.COLOR_RGB2GRAY)
	# 圖像二值化
	ret, thresh = cv.threshold(gray, 127, 255, 0)
	# 計算黑色方塊的4個角點座標
	contours, hierarchy = cv.findContours(thresh, 1, 2)
	for cnt in contours:
	# 求取輪廓的幾何距   
    	M = cv.moments(cnt)
    	# 獲取輪廓的外接矩形,x,y是綠框左上角的像數座標點,w,h是綠框的長,寬
    	x, y, w, h = cv.boundingRect(cnt)
    	# 計算最小輪廓,紅框
    	rect = cv.minAreaRect(cnt)
    	# 計算紅框4個角的像數座標
    	box = cv.boxPoints(rect)
    	# 像數是整型,所以將座標轉成整型
    	box = np.int0(box)


    	if M['m00'] != 0:
        	# print(M)
        	cx = int(M['m10'] / M['m00'])
        	cy = int(M['m01'] / M['m00'])
        	#根據幾何距獲取的中心點,畫出中心圓,被藍線擋了所以看不到
        	cv.circle(image,(np.int(cx),np.int(cy)),2,(0,255,255),-1) 
        	#畫綠框
        	cv.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
        	#畫紅框4個角
        	cv.drawContours(img, [box], 0, (0, 0, 255), 2)
        	for (x, y) in box:
            	cv2.circle(img, (int(x), int(y)), 5, (0, 0, 255), -1)
            	# tl左上角像數座標,tr右上角像數座標,br右下角像數座標,bl左下角像數座標
            	(tl, tr, br, bl) = box
            	# 計算紅框4條邊的中心點
            	(tltrX, tltrY) = midpoint(tl, tr)
            	(blbrX, blbrY) = midpoint(bl, br)
            	(tlblX, tlblY) = midpoint(tl, bl)
            	(trbrX, trbrY) = midpoint(tr, br)
            	# 畫點
            	cv2.circle(img, (int(tltrX), int(tltrY)), 5, (255, 0, 0), -1)
            	cv2.circle(img, (int(blbrX), int(blbrY)), 5, (255, 0, 0), -1)
            	cv2.circle(img, (int(tlblX), int(tlblY)), 5, (255, 0, 0), -1)
            	cv2.circle(img, (int(trbrX), int(trbrY)), 5, (255, 0, 0), -1)
            	# 畫線連接4個點,也就是圖片中2條藍線

            	cv2.line(img, (int(tltrX), int(tltrY)), (int(blbrX), int(blbrY)),
                     (255, 0, 0), 2)
            	cv2.line(img, (int(tlblX), int(tlblY)), (int(trbrX), int(trbrY)),
                     (255, 0, 0), 2)
                # 計算中心點的座標
            	dA = dist.euclidean((tltrX, tltrY), (blbrX, blbrY))
            	dB = dist.euclidean((tlblX, tlblY), (trbrX, trbrY))
            	# 將像數長度轉成實際長度,6.5相當於比例尺,我用的是mm單位,也就是所1mm相當於6.5個像數

            	dimA = dA / 6.5
            	dimB = dB / 6.5
            	# 將計算結果打印在原圖上,也就是黃色的內容

            	cv2.putText(img, "{:.1f}mm".format(dimA),
                        (int(tltrX - 15), int(tltrY - 10)), cv2.FONT_HERSHEY_SIMPLEX,
                        0.65, (0, 255, 255), 2)
            	cv2.putText(img, "{:.1f}mm".format(dimB),
                        (int(trbrX + 10), int(trbrY)), cv2.FONT_HERSHEY_SIMPLEX,
                        0.65, (0, 255, 255), 2)
	cv.imshow("mo", img)
# 啓動攝像頭,設置分辨率
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 800)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 600)
while(cap.isOpened()):
	ret, frame = cap.read()
	img = cv2.flip(frame, -1)
	#創建GUI窗口,形式爲自適應
	cv2.namedWindow("input image", cv2.WINDOW_AUTOSIZE)
	#通過名字將圖像和窗口聯繫
	cv2.imshow("input image", img)
	measure(img)
	# 如果按下P鍵,將保存圖片到D:/Program Files/kk.jpg並退出
	if cv2.waitKey(1) & 0xFF == ord('p'):
    	cv2.imwrite("D:/Program Files/kk.jpg", img)
    	break

參考內容

1.https://www.pyimagesearch.com/2016/03/28/measuring-size-of-objects-in-an-image-with-opencv/
2.https://docs.opencv.org/4.0.0/dd/d49/tutorial_py_contour_features.html
3.https://www.cnblogs.com/XJT2018/p/9952671.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章