看代码前须知:
- 需要固定的摄像头来保证拍摄角度一致
- 需要固定的光源来保证受光面的一致
- 需要固定的检测物体来保证适应所设定的阈值(主要 灰度阈值)
- 需要知道一个物体实际的长度与像素之间的比值 方便做参照
- 使用opencv版本 3.4.2.16
图片:
本人的硬盘一张 图片尺寸:1280X960 拍摄软件:MV 所用镜头:大华
代码片段:
import cv2
# 众所周知的套路
# 转灰度->二值化->寻找前景->物体轮廓位置->找出轮廓坐标->运用已知比值->测量物体实际尺寸
image = cv2.imread('./image/02.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
ret, binary = cv2.threshold(gray, 120, 255, cv2.THRESH_BINARY)
cv2.imshow('image', binary)
binary,contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.RETR_LIST)
for cons in contours:
Area = cv2.contourArea(cons)
if Area > 800000 and Area < 1000000:
print('面积:', Area)
cv2.drawContours(image, cons, -1, (0, 0, 255), 1)
x, y, w, h = cv2.boundingRect(cons)
long = float('%.2f' % (w / 109))
wide = ('%.2f' % (h / 109))
print('坐标:', x, y, w, h)
cv2.putText(image, str('long:{}cm wide:{}cm'.format(long, wide)), (x, y), cv2.CHAIN_APPROX_NONE, 2,
(0, 255, 0),
3)
cv2.imshow("img", image)
else:
continue
cv2.waitKey(0)
运行结果:
二值化图一张
嵌入前景图一张
报错须知:
在cv2.findContours()寻找前景中,可能会出现报错信息
ValueError: not enough values to unpack (expected 3, got 2)
这个是opencv版本问题
opencv2和opencv4中接受的是2个返回值 contours和hierarchy
opencv3中接受的是3个返回值
有人可能会问 啊! 你这109怎么来的!你个大骗子!rnm退钱!!!
桥豆麻袋!!! 打我可以 别!!!打!!!! 脸!!!!!
这个109是根据原像素跟实际的比例测量出来的 109:1 (109个像素点对应1厘米)
这时候又有同学举手问:
博主,这个像素点是怎么确定的?
回答: print打印结果后发现了什么?
坐标分别对应了 x y w h, 分别是左上角点的坐标x,y 和 矩形的宽高w,h就是像素点
宽高都知道了 与实际测量的比值就确定了 接下来不用我多说了吧
实际测量: 长:10.5cm 宽:7.4cm
opencv结论:长:10.57cm 宽:7.36cm
精确不到毫米我也很无奈 要不试试康耐视的软件? 加密狗也就小一万一个