opencv+pycharm+python+USB摄像头

#平台:pycharm
#语言:python
#任务:图像尺寸测量
#器件:平板电脑+USB摄像头
# 最终优化后的版本
from scipy.spatial.distance import euclidean
from imutils import perspective
from imutils import contours
import cv2
import numpy as np
import imutils

#红色轮廓线,黄色最小外接矩形
cam = True
cap = cv2.VideoCapture(1)  # 视频捕获 打开摄像头
cap.set(3, 960)  # 3序号 视频流的帧的宽度960
cap.set(4, 540)  # 4序号 视频流的帧的高度540
cap.set(10, 100)  # 10序号 视频流的帧的亮度
image = cv2.imread("G:/pycharmonemy/5.png")
while True:
    if cam:
        success, img = cap.read()
    else:
        img = cv2.imread(image)
    # 预处理
    imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 灰度图
    imgBlur = cv2.GaussianBlur(imgGray, (5, 5), 0)  # 高斯模糊  高斯核大小5*5 标准差取0  模糊处理便于寻找边缘和特征点
    imgCanny = cv2.Canny(imgBlur, 100, 100)  # Canny边缘检测  用双阈值确定边缘 阈值越小,能够捕获越多的边缘信息
    kernel = np.ones((5, 5), np.uint8)  # 定义8位无符号整数5*5大小
    imgDilation = cv2.dilate(imgCanny, kernel, iterations=1)  # 膨胀  膨胀处理可以将断裂开的目标物进行合并,便于对其整体的提取
    imgErode = cv2.erode(imgDilation, kernel, iterations=1)  # 腐蚀  腐蚀处理可以将粘连在一起的不同目标物分离,并可以将小的颗粒噪声去除
    cnts = cv2.findContours(imgErode.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    cnts = imutils.grab_contours(cnts)
    # 设置最左边的轮廓为参考对象,从左到右对轮廓进行排序
    if len(cnts):
        (cnts, _) = imutils.contours.sort_contours(cnts)
    # 删除小轮廓
    if len(cnts):
        cnts = [x for x in cnts if cv2.contourArea(x) > 100]
    # 参考对象尺寸选择4cm长,2cm宽的长方形
    if len(cnts):
        ref_object = cnts[0]
        # 计算最小的外接矩形
        box = cv2.minAreaRect(ref_object)
        box = cv2.boxPoints(box)
        box = np.array(box, dtype="int")
        # 对轮廓点进行排序 左上角,右上角,右下角,左下角
        box = perspective.order_points(box)
        # 获取4个坐标点并计算中心点坐标
        (tl, tr, br, bl) = box
        # 根据左上角参考物体,计算单位长度中的像素个数
        dist_in_wpixel = euclidean(tl, tr)
        dist_in_hpixel = euclidean(tr, br)
        dist_in_wcm = 4.0
        dist_in_hcm = 2.0
        pixel_per_hcm = dist_in_hpixel / dist_in_hcm  # 计算纵向比例系数
        pixel_per_wcm = dist_in_wpixel / dist_in_wcm  # 计算横向比例系数
        # 轮廓检测
        contours, hierarchy = cv2.findContours(imgErode.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
        for obj in contours:
            area = cv2.contourArea(obj)  # 计算轮廓内区域的面积
            if area > 500:
                cv2.drawContours(img, obj, -1, (0, 0, 255), 3)  # 绘制红色轮廓线
                peri = cv2.arcLength(obj, True)  # 计算轮廓的周长,true表示轮廓为封闭
                approx = cv2.approxPolyDP(obj, 0.02 * peri, True)  # 获取轮廓角点坐标
                CornerNum = len(approx)  # 统计轮廓角点的数量
                x, y, w, h = cv2.boundingRect(approx)  # 获取坐标值和宽度、高度
                cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 255), 2)  # 绘制边界框
                # 轮廓对象分类 根据点的个数确定图形形状
                if CornerNum == 4:
                    aspRatio = w / float(h)
                    if aspRatio > 0.96 and aspRatio < 1.04:
                        objectshape = "square"  # 判断为正方形
                    else:
                        objectshape = "rectangle"  # 判断为长方形
                elif CornerNum > 4:
                    objectshape = "circle"  # 判断为圆形
                else:
                    objectshape = "None"  # 判断为不符合要求的形状
                cv2.putText(img, objectshape, (x + (w // 2) - 10, y + (h // 2) - 10), cv2.FONT_HERSHEY_COMPLEX, 0.7, (0, 0, 0),
                    2)  # 标注图形类别
    # 绘制待测图形最小外接矩形
        for cnt in range(len(cnts)):
            box = cv2.minAreaRect((cnts)[cnt])
            box = cv2.boxPoints(box)
            box = np.array(box, dtype="int")
            box = perspective.order_points(box)
            (tl, tr, br, bl) = box
            mid_pt_horizontal = (tl[0] + int(abs(tr[0] - tl[0])/2), tl[1] + int(abs(tr[1] - tl[1])/2))
            mid_pt_verticle = (tr[0] + int(abs(tr[0] - br[0])/2), tr[1] + int(abs(tr[1] - br[1])/2))
            wid = euclidean(tl, tr)/pixel_per_wcm
            ht = euclidean(tr, br)/pixel_per_hcm
            cv2.putText(img, "{:.2f}cm".format(wid), (int(mid_pt_horizontal[0] - 15), int(mid_pt_horizontal[1] - 10)),
                cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 0), 2)
            cv2.putText(img, "{:.2f}cm".format(ht), (int(mid_pt_verticle[0] + 10), int(mid_pt_verticle[1])),
                cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 0), 2)

   
    cv2.imshow("pattern measurement", img)
    if cv2.waitKey(1) & 0xFF == ord('k'):  # 检测键盘,按下k键时退出摄像头拍摄界面
                break

效果展示
在这里插入图片描述
在这里插入图片描述

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值