QT+Python+OpenCV+ffmpeg(第二集)

QT+Python+OpenCV+视觉尺寸测量

开源项目Time-Object-Measurement-maste:源代码(2K相机)

ObjectMeasurement.py

import cv2  # 导入OpenCV库,用于图像处理
import utlis  # 导入自定义的工具库,可能包含一些辅助函数

# 配置参数
webcam = True  # 是否使用摄像头,True表示使用,False表示使用静态图片
image_path = 'C:/Users/CJL/Desktop/Real-Time-Object-Measurement-master/1.jpg'  # 静态图片的路径
cap = cv2.VideoCapture(0)  # 打开默认摄像头(设备ID为0)
cap.set(10, 160)  # 设置摄像头的亮度(属性ID 10, 值为160)
cap.set(3, 2560)  # 设置摄像头捕获图像的宽度为2560
cap.set(4, 1440)  # 设置摄像头捕获图像的高度为1440
scale = 3  # 图像处理时的缩放比例
width_processed = 210 * scale  # 处理后的图像宽度
height_processed = 297 * scale  # 处理后的图像高度


def process_image(img, scale, width_processed, height_processed):
    """
    处理图像,包括获取轮廓、变换图像、测量对象尺寸并绘制结果。
    :param img: 输入的原始图像
    :param scale: 缩放比例
    :param width_processed: 处理后的图像宽度
    :param height_processed: 处理后的图像高度
    """
    img_contours, contours = utlis.getContours(img, minArea=50000, filter=4)  # 获取图像中的轮廓
    if contours:  # 如果检测到轮廓
        biggest = contours[0][2]  # 获取最大的轮廓
        img_warped = utlis.warpImg(img, biggest, width_processed, height_processed)  # 根据最大轮廓变换图像
        img_contours2, contours2 = utlis.getContours(img_warped, minArea=2000, filter=4, cThr=[50, 50], draw=False)
        # 在变换后的图像中再次获取轮廓,不进行绘制
        for obj in contours2:
            cv2.polylines(img_contours2, [obj[2]], True, (0, 255, 0), 2)  # 绘制轮廓
            points = utlis.reorder(obj[2])  # 重新排序轮廓点
            width = round((utlis.findDis(points[0][0] // scale, points[1][0] // scale) / 10), 1)  # 计算宽度
            height = round((utlis.findDis(points[0][0] // scale, points[2][0] // scale) / 10), 1)  # 计算高度
            # 绘制宽度和高度线
            cv2.arrowedLine(img_contours2, tuple(points[0][0]), tuple(points[1][0]), (255, 0, 255), 3, 8, 0, 0.05)
            cv2.arrowedLine(img_contours2, tuple(points[0][0]), tuple(points[2][0]), (255, 0, 255), 3, 8, 0, 0.05)
            x, y, w, h = obj[3]  # 获取轮廓的边界框
            # 在图像上绘制宽度和高度文本
            cv2.putText(img_contours2, f'{width}cm', (x + 30, y - 10), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1.5,
                        (255, 0, 255), 2)
            cv2.putText(img_contours2, f'{height}cm', (x - 70, y + h // 2), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1.5,
                        (255, 0, 255), 2)
        cv2.imshow('Processed Image', img_contours2)  # 显示处理后的图像


def main_loop():
    """
    主循环函数,用于持续读取摄像头或图像,并进行处理。
    """
    while True:
        if webcam:  # 如果使用摄像头
            success, img = cap.read()  # 读取摄像头图像
            if not success:  # 如果读取失败
                print("Failed to read from camera")
                break
        else:  # 如果使用静态图片
            img = cv2.imread(image_path)  # 读取静态图片
            if img is None:  # 如果读取失败
                print("Failed to read image from path")
                break

        process_image(img, scale, width_processed, height_processed)  # 处理图像
        img_resized = cv2.resize(img, (0, 0), None, 0.5, 0.5)  # 缩放原始图像以便显示
        cv2.imshow('Original Image', img_resized)  # 显示原始图像
        if cv2.waitKey(1) & 0xFF == ord('q'):  # 如果按下'q'键,则退出循环
            break


if __name__ == "__main__":
    main_loop()  # 运行主循环
    cap.release()  # 释放摄像头资源
    cv2.destroyAllWindows()  # 销毁所有OpenCV窗口

utlis.py

import cv2  # 导入OpenCV库,用于图像处理
import numpy as np  # 导入NumPy库,用于数组和矩阵运算


def getContours(img, cThr=[100, 100], showCanny=False, minArea=1000, filter=0, draw=False):
    """
    获取图像中的轮廓

    参数:
    img: 输入的图像
    cThr: Canny边缘检测的阈值,格式为[低阈值, 高阈值],默认为[100, 100]
    showCanny: 是否显示Canny边缘检测结果,默认为False
    minArea: 轮廓的最小面积,低于该值的轮廓将被过滤掉,默认为1000
    filter: 轮廓边数的过滤条件,默认为0(不过滤)
    draw: 是否在原图上绘制轮廓,默认为False

    返回:
    img: 处理后的图像(如果draw为True,则为绘制了轮廓的图像)
    finalCountours: 检测到的轮廓信息列表,每个元素包含[边数, 面积, 近似多边形, 边界框, 原始轮廓]
    """
    imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 将图像转换为灰度图
    imgBlur = cv2.GaussianBlur(imgGray, (5, 5), 1)  # 使用高斯模糊平滑图像
    imgCanny = cv2.Canny(imgBlur, cThr[0], cThr[1])  # 使用Canny算法检测边缘
    kernel = np.ones((5, 5))  # 创建5x5的卷积核
    imgDial = cv2.dilate(imgCanny, kernel, iterations=3)  # 膨胀操作,增强边缘
    imgThre = cv2.erode(imgDial, kernel, iterations=2)  # 腐蚀操作,去除杂点

    if showCanny:
        cv2.imshow('Canny', imgThre)  # 显示Canny边缘检测结果

    contours, hierarchy = cv2.findContours(imgThre, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)  # 查找轮廓
    finalCountours = []

    for i in contours:
        area = cv2.contourArea(i)  # 计算轮廓面积
        if area > minArea:
            peri = cv2.arcLength(i, True)  # 计算轮廓周长
            approx = cv2.approxPolyDP(i, 0.02 * peri, True)  # 使用多边形逼近轮廓
            bbox = cv2.boundingRect(approx)  # 获取轮廓的边界框

            if filter > 0:
                if len(approx) == filter:  # 根据边数过滤轮廓
                    finalCountours.append([len(approx), area, approx, bbox, i])
            else:
                finalCountours.append([len(approx), area, approx, bbox, i])

    finalCountours = sorted(finalCountours, key=lambda x: x[1], reverse=True)  # 按面积降序排序轮廓

    if draw:
        for con in finalCountours:
            cv2.drawContours(img, con[4], -1, (0, 0, 255), 3)  # 在图像上绘制轮廓

    return img, finalCountours


def reorder(myPoints):
    """
    重新排序四个点的顺序,使其符合:左上,右上,右下,左下

    参数:
    myPoints: 输入的四个点坐标,通常是一个形状为(4, 2)或(8,)的数组

    返回:
    myPointsNew: 重新排序后的点坐标
    """
    myPointsNew = np.zeros_like(myPoints)
    myPoints = myPoints.reshape((4, 2))

    add = myPoints.sum(1)  # 按x+y的值排序,找到最小和最大的点
    myPointsNew[0] = myPoints[np.argmin(add)]  # 左上点
    myPointsNew[3] = myPoints[np.argmax(add)]  # 右下点

    diff = np.diff(myPoints, axis=1)  # 按x-y的值排序,找到最小和最大的点
    myPointsNew[1] = myPoints[np.argmin(diff)]  # 右上点
    myPointsNew[2] = myPoints[np.argmax(diff)]  # 左下点

    return myPointsNew


def warpImg(img, points, w, h, pad=20):
    """
    根据给定的四个点,对图像进行透视变换

    参数:
    img: 输入的图像
    points: 用于透视变换的四个点坐标
    w: 变换后图像的宽度
    h: 变换后图像的高度
    pad: 变换后图像四周的裁剪边距,默认为20

    返回:
    imgWarp: 经过透视变换和裁剪后的图像
    """
    points = reorder(points)  # 重新排序点
    pts1 = np.float32(points)  # 原始点坐标
    pts2 = np.float32([[0, 0], [w, 0], [0, h], [w, h]])  # 目标点坐标
    matrix = cv2.getPerspectiveTransform(pts1, pts2)  # 计算透视变换矩阵
    imgWarp = cv2.warpPerspective(img, matrix, (w, h))  # 进行透视变换
    imgWarp = imgWarp[pad:imgWarp.shape[0] - pad, pad:imgWarp.shape[1] - pad]  # 裁剪图像

    return imgWarp


def findDis(pts1, pts2):
    """
    计算两点之间的欧氏距离

    参数:
    pts1: 第一个点的坐标 (x1, y1)
    pts2: 第二个点的坐标 (x2, y2)

    返回:
    距离值
    """
    return ((pts2[0] - pts1[0]) ** 2 + (pts2[1] - pts1[1]) ** 2) ** 0.5

开源项目Time-Object-Measurement-maste:效果展示

在这里插入图片描述

开源项目Time-Object-Measurement-maste:修改源代码,接入海康威视摄像机(1080p)

# 配置参数
webcam = True  # 设置是否使用网络摄像头(RTSP流)
url = "rtsp://admin:Admin123@192.168.31.64:554/h264/ch33/main/av_stream"  # RTSP流的URL
cap = cv2.VideoCapture(url)  # 创建VideoCapture对象,用于从RTSP流捕获视频
cap.set(10, 160)  # 设置摄像头的亮度(可能不适用于所有摄像头或流)
cap.set(3, 1920)  # 设置捕获视频的宽度
cap.set(4, 1080)  # 设置捕获视频的高度
scale = 3  # 图像处理的缩放比例
width_processed = 210 * scale  # 处理后的图像宽度
height_processed = 297 * scale  # 处理后的图像高度

开源项目Time-Object-Measurement-maste:运行效果

模糊

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Jetson Nano B01上安装OpenCV并添加FFmpeg支持,可以按照以下步骤进行操作: 1. 首先,下载OpenCV 4.1.1和对应的OpenCV-contrib 4.1.1版本。你可以从官方网站下载这些文件,链接如下: - OpenCV 4.1.1: https://github.com/opencv/opencv/tags?after=4.3.0 - OpenCV-contrib 4.1.1: https://github.com/opencv/opencv_contrib/tags?after=3.4.12 2. 将下载的文件解压到Jetson Nano上。 3. 打开终端,进入解压后的OpenCV文件夹,创建一个名为"build"的文件夹,并进入该文件夹: ``` cd opencv_4.1.1 mkdir build cd build ``` 4. 运行以下命令进行CMake配置: ``` sudo cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_PNG=OFF -DBUILD_TIFF=OFF -DBUILD_TBB=ON -DBUILD_JPEG=OFF -DBUILD_JASPER=OFF -DBUILD_ZLIB=OFF -DBUILD_EXAMPLES=ON -DBUILD_opencv_java=OFF -DBUILD_opencv_python2=OFF -DBUILD_opencv_python3=ON -DENABLE_PRECOMPILED_HEADERS=OFF -DWITH_OPENCL=OFF -DWITH_OPENMP=OFF -DWITH_LIBV4L=ON -DWITH_FFMPEG=ON -DWITH_GSTREAMER=OFF -DWITH_GSTREAMER_0_10=OFF -DWITH_CUDA=ON -DWITH_GTK=ON -DWITH_VTK=OFF -DWITH_V4L=ON -DWITH_TBB=ON -DWITH_QT=ON -DWITH_OPENGL=ON -DWITH_1394=OFF -DWITH_OPENEXR=OFF -DCUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda-10.2 -DCUDA_ARCH_BIN=5.3 -DCUDA_ARCH_PTX="" -DINSTALL_C_EXAMPLES=ON -DOPENCV_ENABLE_NONFREE=ON -DINSTALL_TESTS=OFF -DWITH_GTK_2_X=ON -DOPENCV_EXTRA_MODULES_PATH=../../opencv_contrib-4.1.1/modules .. ``` 5. 运行以下命令进行编译: ``` sudo make -j8 ``` 6. 等待编译完成(进度条达到100%)。 完成上述步骤后,你应该成功在Jetson Nano B01上安装了OpenCV,并添加了FFmpeg支持。请注意,这些步骤是基于引用\[2\]中提供的信息进行的。 #### 引用[.reference_title] - *1* *2* *3* [jetson nano装opencv4.1.1](https://blog.csdn.net/weixin_45235219/article/details/128840418)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值