opencv学习——识别特定的图像(简单版)

原视频就是坤坤的视频

我们的任务就是把篮球圈出

截取图片分析:

import cv2
import numpy as np

# 读取图像
image_path = r'D:\desktop\basketball.png'
image = cv2.imread(image_path)

# 转换为HSV颜色空间
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

# 定义橙色(篮球)的HSV范围
lower_orange = np.array([0, 100, 100])
upper_orange = np.array([20, 255, 255])

# 创建掩码
mask = cv2.inRange(hsv, lower_orange, upper_orange)

# 查找轮廓
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 遍历所有轮廓
for contour in contours:
    # 计算轮廓的边界框
    x, y, w, h = cv2.boundingRect(contour)
    
    # 绘制蓝色边框
    cv2.rectangle(image, (x, y), (x + w, y + h), (255, 0, 0), 2)

# 显示结果图像
cv2.imshow('Result', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

思路

1,将传统的rgb转化为hsv,并定义篮球的颜色的范围

2,根据颜色范围创建掩码,即满足颜色变为白色,其余为黑色

3,查找轮廓

解析

cv2.findContours:该函数用于从二值图像中提取轮廓信息。轮廓可以理解为图像中具有相同颜色或灰度值的连续点集的边界。

参数

    • mask:输入的二值图像(掩码)。
    • cv2.RETR_EXTERNAL:检索模式,只返回最外层的轮廓(即不包括内部轮廓)。
    • cv2.CHAIN_APPROX_SIMPLE:轮廓近似方法,压缩水平、垂直和对角线方向的冗余点,只保留关键点。
np.array([x, y, z])

三个值分别代表了色调(Hue)、饱和度(Saturation)和亮度(Value)

 

根据HSV调整的结果来确定

原数据:

调试HSV:

import cv2
import numpy as np

def nothing(x):
    pass

# 通过Opencv读取图片信息
img = cv2.imread(r'D:\test\py\cv2\zhiyin\basketball.png')
rows, cols, channels = img.shape
cv2.imshow("src", img)
cv2.namedWindow('img2', 1)

# 创建6个滑条用来操作HSV3个分量的上下截取界限
cv2.createTrackbar('Hlow','img2',62,180,nothing)
cv2.createTrackbar('Hup','img2',99,180,nothing)
cv2.createTrackbar('Slow','img2',198,255,nothing)
cv2.createTrackbar('Sup','img2',255,255,nothing)
cv2.createTrackbar('Vlow','img2',150,255,nothing)
cv2.createTrackbar('Vup','img2',255,255,nothing)

hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

while(1):
    hlow = cv2.getTrackbarPos('Hlow', 'img2')
    hup = cv2.getTrackbarPos('Hup', 'img2')
    slow = cv2.getTrackbarPos('Slow', 'img2')
    sup = cv2.getTrackbarPos('Sup', 'img2')
    vlow = cv2.getTrackbarPos('Vlow', 'img2')
    vup = cv2.getTrackbarPos('Vup', 'img2')
    
    lower_red = np.array([hlow, slow, vlow])
    upper_red = np.array([hup, sup, vup])
    mask = cv2.inRange(hsv, lower_red, upper_red)
    img2 = cv2.bitwise_and(img, img, mask=mask)

    cv2.imshow("img2", img2)
    k = cv2.waitKey(1) & 0xFF
    if k == 27: # ESC键退出
        break

# 清理资源
cv2.destroyAllWindows()

调试后的结果

Hlow: 0 Hup: 20 Slow: 100 Sup: 255 Vlow: 100 Vup: 255

  • Hlow (色调下限) = 0Hup (色调上限) = 20
  • Slow (饱和度下限) = 80Sup (饱和度上限) = 255
  • Vlow (亮度下限) = 130Vup (亮度上限) = 255

调整后的数据:

视频源码:

import cv2
import numpy as np  

min_contour_area = 2000

# 视频文件的路径
video_path = r'D:\test\py\cv2\zhiyin\zhiyin.mp4'

# 使用OpenCV打开视频文件
cap = cv2.VideoCapture(video_path)

# 检查视频是否成功打开
if not cap.isOpened():
    print("Error: Could not open video.")
else:
    # 获取原始视频的宽度和高度
    original_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    original_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
    print(f"Original Video Size: {original_width}x{original_height}")

    # 设置缩放比例
    scale_percent = 50  # 缩小到原尺寸的50%

    # 计算新的尺寸
    new_width = int(original_width * scale_percent / 100)
    new_height = int(original_height * scale_percent / 100)
    dim = (new_width, new_height)

    # 设定加速倍数
    speed_factor = 3  # 加快3倍

    while True:
        # 逐帧读取视频
        ret, frame = cap.read()
        
        # 如果正确读取了帧,则ret为True
        if not ret:
            print("Reached the end of the video or an error occurred.")
            break
        
        # 调整帧的大小
        resized_frame = cv2.resize(frame, dim, interpolation=cv2.INTER_AREA)
        hsv = cv2.cvtColor(resized_frame, cv2.COLOR_BGR2HSV)

        # 定义橙色(篮球)的HSV范围
        lower_orange = np.array([0, 80, 130])
        upper_orange = np.array([20, 255, 255])

        # 创建掩码
        mask = cv2.inRange(hsv, lower_orange, upper_orange)

        # 查找轮廓
        contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

        # 遍历所有轮廓
        for contour in contours:
            # 计算轮廓面积
            area = cv2.contourArea(contour)
            
            # 如果面积大于设定的阈值,则进行处理
            if area > min_contour_area:
                # 计算轮廓的边界框
                x, y, w, h = cv2.boundingRect(contour)
                
                # 绘制蓝色边框
                cv2.rectangle(resized_frame, (x, y), (x + w, y + h), (255, 0, 0), 2)

        
        # 显示结果帧
        cv2.imshow('Resized Video Playback', resized_frame)
        
        # 按下 'q' 键退出
        if cv2.waitKey(int(1000 / cap.get(cv2.CAP_PROP_FPS) / speed_factor)) & 0xFF == ord('q'):
            break
    
    # 完成后释放捕获对象并关闭所有OpenCV窗口
    cap.release()
    cv2.destroyAllWindows()

经过调整后,框定的面积增大,但是在视频中有时gege突脸的时候会误判,通过面积筛选也不能完美解决这个问题,所以在高精度的识别中就需要做取舍,降低识别面积来提高精度

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值