Code
import cv2 as cv
import numpy
def measure_object(image):
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
# 灰度圖gary轉(zhuǎn)為二值圖(黑白圖)--->輸出ret 閾值、binary 二值圖
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU)
print("threshold value", ret)
cv.imshow("binary image", binary)
dst = cv.cvtColor(binary, cv.COLOR_GRAY2BGR)
# 找二值圖binary的輪廓妻往,cv.RETR_EXTERNAL(只檢索外部輪廓)、cv.RETR_TREE(檢索全部輪廓)
contours, hierarchy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
# 遍歷全部輪廓
for i, contour in enumerate(contours):
# 輪廓面積
# area = cv.contourArea(contour)
x, y, w, h = cv.boundingRect(contour) # 輪廓外接矩形面積
mm = cv.moments(contour) # 幾何矩
print(type(mm))
if mm['m00']:
cx = mm['m10'] / mm['m00']
cy = mm['m01'] / mm['m00']
"""
circle(img, center, radius, color[, thickness[, lineType[, shift]]]) -> img
#在原圖img上繪制圓(圓心np.int(cx), np.int(cy))
半徑 3 ,顏色(0,255,0)綠,線寬2(如果為負(fù)數(shù)則填充)
"""
cv.circle(image, (numpy.int(cx), numpy.int(cy)), 3, (0, 255, 255), -1)
"""
ectangle(img, pt1, pt2, color[, thickness[, lineType[, shift]]]) -> img
在原圖img上繪制外接矩形 瀑踢,左上角端點(diǎn)坐標(biāo)(x, y),寬高(x + w, y + h)
顏色(0,0,255)载弄,線寬2(如果為負(fù)數(shù)則填充)
"""
cv.rectangle(image, (x, y), (x+w, y+h), (0, 0, 255), 2)
"""
approxPolyDP(curve, epsilon, closed[, approxCurve]) -> approxCurve
curve-擬合曲線
epsilon-擬合曲線條數(shù)(int)
closed-擬合曲線是否閉合(True or False)
多邊形擬合
"""
"""
繪制輪廓
drawContours(image, contours, contourIdx, color[, thickness[, lineType[, hierarchy[, maxLevel[, offset]]]]]) -> image
image-原圖上繪制輪廓
contours-全部輪廓
contourIdx-輪廓系數(shù)i
color-顏色
thickness-線寬
"""
"""
approxCurve = cv.approxPolyDP(contour, 10, True)
print(approxCurve.shape)
# 畫輪廓多邊形擬合數(shù)目>6的圖形輪廓為紅色
if approxCurve.shape[0] > 6:
cv.drawContours(dst, contours, i, (0, 0, 255), 2)
# 畫輪廓多邊形擬合數(shù)目=4的圖形輪廓為綠色
elif approxCurve.shape[0] == 4:
cv.drawContours(dst, contours, i, (0, 255, 0), 2)
# 畫輪廓多邊形擬合數(shù)目=3的圖形輪廓為藍(lán)
elif approxCurve.shape[0] == 3:
cv.drawContours(dst, contours, i, (255, 0, 0), 2)
# 畫其余數(shù)目的輪廓多邊形擬合的圖形輪廓為黃色
else:
cv.drawContours(dst, contours, i, (0, 255, 255), 2)
"""
cv.imshow("meassure-contours", image)
src = cv.imread("./data/pic1.png", cv.IMREAD_COLOR)
cv.namedWindow("lena", cv.WINDOW_AUTOSIZE)
cv.imshow("lena", src)
measure_object(src)
cv.waitKey(0)
cv.destroyAllWindows()
獲取圖像的外接矩形boundingRect和幾何距moments
多邊形逼近approxPolyDP
# 10是與閾值的間隔大小汇在,越小越易找出,True是是否找閉合圖像
approxCurve = cv.approxPolyDP(contour, 10, True)
print(approxCurve.shape)
# 畫輪廓多邊形擬合數(shù)目>6的圖形輪廓為紅色
if approxCurve.shape[0] > 6:
cv.drawContours(dst, contours, i, (0, 0, 255), 2)
# 畫輪廓多邊形擬合數(shù)目=4的圖形輪廓為綠色
elif approxCurve.shape[0] == 4:
cv.drawContours(dst, contours, i, (0, 255, 0), 2)
# 畫輪廓多邊形擬合數(shù)目=3的圖形輪廓為藍(lán)
elif approxCurve.shape[0] == 3:
cv.drawContours(dst, contours, i, (255, 0, 0), 2)
# 畫其余數(shù)目的輪廓多邊形擬合的圖形輪廓為黃色
else:
cv.drawContours(dst, contours, i, (0, 255, 255), 2)
API
cv2.moments()用來計(jì)算圖像中的中心矩(最高到三階)
outImg, contours, hireachy = cv2.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
函數(shù)有3個(gè)參數(shù)Arguments(變量)
PS:百度outline參數(shù)是opencv3有刹缝,opencv2跟opencv4沒有碗暗,恰好我是用pycharm安裝的是opencv4
1、source image(源圖像)一般是 binary 二值圖像
2梢夯、contour retrieval mode(輪廓檢索模式) 一般選用 cv.RETR_EXTERNAL(只檢索外部輪廓) cv.RETR_TREE(檢索全部輪廓)
3言疗、contour approximation method(輪廓近似法)一般選用 cv.CHAIN_APPROX_SIMPLE
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU)
1、gray-源BGR圖像轉(zhuǎn)化的灰度圖像
2颂砸、像素閾值
3噪奄、cv.THRESH_BINARY_INV | cv.THRESH_OTSU -二值圖像轉(zhuǎn)化方法
def approxPolyDP(curve, epsilon, closed, approxCurve=None):
approxCurve = cv.approxPolyDP(contour,4,True) #4是與閾值的間隔大小,越小越易找出人乓,True是是否找閉合圖像
real signature unknown; restored from doc
第一個(gè)參數(shù)curve:輸入的點(diǎn)集勤篮,直接使用輪廓點(diǎn)集contour
第二個(gè)參數(shù)epsilon:指定的精度,也即是原始曲線與近似曲線之間的最大距離色罚。
第三個(gè)參數(shù)closed:若為true,則說明近似曲線是閉合的碰缔,反之,若為false戳护,則斷開金抡。
第四個(gè)參數(shù)approxCurve:輸出的點(diǎn)集,當(dāng)前點(diǎn)集是能最小包容指定點(diǎn)集的腌且。畫出來即是一個(gè)多邊形梗肝;
approxCurve:輸出的點(diǎn)集,當(dāng)前點(diǎn)集是能最小包容指定點(diǎn)集的铺董。畫出來即是一個(gè)多邊形巫击;
print(approxCurve) #打印每個(gè)輪廓的特征點(diǎn)
print(approxCurve.shape) #打印該點(diǎn)集的shape,第一個(gè)數(shù)是代表了點(diǎn)的個(gè)數(shù)精续,也就是邊長(zhǎng)連接逼近數(shù)