OpenCV的一些图像处理算法

OpenCV的一些图像处理算法

训练完电赛滚球题,刚比完数据赛,总结一下用到的一些图像处理算法
(写到后面觉得好长,数据赛的写在另一篇博客https://blog.csdn.net/qq_45615475/article/details/112860120)
阈值提取
OpenCV的一些图像处理算法_第1张图片

#定义各类颜色阈值范围
import numpy as np
#黑色
lower_black=np.array([0,0,0])
upper_black=np.array([180,255,46])
#灰色
lower_gray=np.array([0,0,46])
upper_gray=np.array([180,43,220])
#白色
lower_white=np.array([0,0,221])
upper_white=np.array([180,30,255])
#红色
lower_red1=np.array([0,43,46])
upper_red1=np.array([10,255,255])
lower_red2=np.array([156,43,46])
upper_red2=np.array([180,255,255])
#橙色
lower_orange=np.array([11,43,46])
upper_orange=np.array([25,255,255])
#黄色
lower_yellow=np.array([26,43,46])
upper_yellow=np.array([34,255,255])
#青色
lower_qin=np.array([78,43,46])
upper_qin=np.array([99,255,255])
#蓝色
lower_blue=np.array([100,43,46])
upper_blue=np.array([124,255,255])
#紫色
lower_purple=np.array([125,43,46])
upper_purple=np.array([155,255,255])
img_path='Test/Test1.png'
img=cv2.imread(img_path)
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)#转换为HSV空间
mask = cv2.inRange(hsv, lower_red, upper_red)#根据阈值提取红色,想提取其他颜色就改为对应阈值即可

二值化

gray_img = cv2.cvtColor(cropped, cv2.COLOR_BGRA2GRAY)#图像灰度化
ret,thresh = cv2.threshold(gray_img,80,255,cv2.THRESH_BINARY)#需要设置提取阈值

霍夫圆检测
小球识别一开始用的方案,但太耗时,最后还是直接色块检测

lower = np.array([0, 0, 0])  # 设定颜色的阈值下限
upper = np.array([120, 120, 120])  # 设定颜色的阈值上限
#  消除噪声
mask = cv2.inRange(hsv, lower, upper)  # 设定掩膜取值范围
#bila = cv2.bilateralFilter(mask, 10, 200, 200)  # 双边滤波消除噪声
#opening = cv2.morphologyEx(bila, cv2.MORPH_OPEN, kernel)  # 形态学开运算
#closing = cv2.morphologyEx(opening, cv2.MORPH_CLOSE, kernel)  # 形态学开运算
#edges = cv2.Canny(closing, 50, 100) # 边缘识别
edges = cv2.Canny(mask, 50, 100) # 边缘识别
circles = cv2.HoughCircles(
             edges, cv2.cv.CV_HOUGH_GRADIENT, 1, 100, param1=100, param2=10, minRadius=10, maxRadius=500)
          if circles is not None:  # 如果识别出圆
            for circle in circles[0]:
                 #  获取圆的坐标与半径
                 x = int(circle[0])
                 y = int(circle[1])
                 r = int(circle[2])
                 cv2.circle(frame, (x, y), r, (0, 0, 255), 3)  # 标记圆
                 cv2.circle(frame, (x, y), 3, (255, 255, 0), -1)  # 标记圆心
                 text = 'x:  '+str(x)+' y:  '+str(y)
                 cv2.putText(frame, text, (10, 30), font, 1, (0, 255, 0), 2)  # 显示圆心位置
         else:
             # 如果识别不出,显示圆心不存在
            cv2.putText(frame, 'x: None y: None', (10, 30), font, 1, (0, 255, 0), 2)
#输入图像,输出画圆的图像
def Get_Circles(frame):

    gray = cv2.cvtColor(frame, cv2.COLOR_BGRA2GRAY)
    img = cv2.medianBlur(gray, 7)
    circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, 1, 50, param1=100, param2=30, minRadius=70, maxRadius=200)#霍夫圆检测
    if circles is not None:
        circles = np.uint16(np.around(circles))
        for i in circles[0, :]:  # 在图片上画圆和圆心
            cv2.circle(frame, (i[0], i[1]), i[2], (0, 255, 0), 2)
            cv2.circle(frame, (i[0], i[1]), 2, (0, 0, 255), 3)
    return frame
#找红球
def Get_Red_Circles(frame):
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
    mask = cv2.inRange(hsv, lower_red, upper_red)
    res = cv2.bitwise_and(frame, frame, mask=mask)
    gray = cv2.cvtColor(res, cv2.COLOR_BGRA2GRAY)
    img = cv2.medianBlur(gray, 7)
    circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, 1, 50, param1=100, param2=30, minRadius=70, maxRadius=200)#霍夫圆检测
    if circles is not None:
        circles = np.uint16(np.around(circles))
        for i in circles[0, :]:  # 在图片上画圆和圆心
            cv2.circle(frame, (i[0], i[1]), i[2], (0, 255, 0), 2)
            cv2.circle(frame, (i[0], i[1]), 2, (0, 0, 255), 3)
    return frame

色块检测

cnts = cv2.findContours(thresh1.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]  #轮廓检测
#如果存在轮廓  
if len(cnts) > 0:  
    #找到面积最大的轮廓  
    c = max(cnts, key = cv2.contourArea)  
    #确定面积最大的轮廓的外接圆  
    ((center_x, center_y), radius) = cv2.minEnclosingCircle(c)  
    #计算轮廓的矩  
    # M = cv2.moments(c)  
    #计算质心  
    cv2.circle(frame, (int(center_x), int(center_y)), int(radius), (0, 255, 255), 2)  
    cv2.circle(frame, None, 5, (0, 0, 255), -1)
    print('红色色块的中心坐标',(int(center_x),int(center_y)))
#通过二值化和色块检测得到小球坐标
lower_red=np.array([156,43,46])
upper_red=np.array([180,255,255])
def Binary_Get_Ball(frame,show,area,thr):
    cropped = frame[area[0]:area[1], area[2]:area[3]]  #(上,下)(左,右)
    gray_img = cv2.cvtColor(cropped, cv2.COLOR_BGRA2GRAY)#图像灰度化
    ret,thresh=cv2.threshold(gray_img,thr[0],thr[1],cv2.THRESH_BINARY)
    thresh=255-thresh
    cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]  #轮廓检测
    #如果存在轮廓  
    if len(cnts) > 0:  
        #找到面积最大的轮廓  
        c = max(cnts, key = cv2.contourArea)  
        #确定面积最大的轮廓的外接圆  
        ((center_x, center_y), radius) = cv2.minEnclosingCircle(c)  
        if (show==True): 
            cv2.circle(cropped, (int(center_x), int(center_y)), int(radius), (0, 255, 255), 2)  
            cv2.circle(cropped, None, 5, (0, 0, 255), -1)
        print('红色色块的中心坐标',(int(center_x),int(center_y)))
    else:
        center_x=0
        center_y=0
        radius=0
    return center_x,center_y,radius,cropped

电赛滚球题最终方案
可见我另一篇文章https://blog.csdn.net/qq_45615475/article/details/112859548

形态学开运算/闭运算
好像有以下代码可以执行

opening = cv2.morphologyEx(bila, cv2.MORPH_OPEN, kernel) # 形态学开运算 
closing = cv2.morphologyEx(opening, cv2.MORPH_CLOSE, kernel) # 形态学闭运算

但我一般都是直接膨胀腐蚀(闭运算)或者腐蚀膨胀(开运算)看每一步的效果效果

#iterations为整数,可调,越大效果越强
no_img1 = cv2.dilate(no_img1, None, iterations=1)#膨胀
no_img1 = cv2.erode(no_img1, None, iterations=1)#腐蚀

滤波
双边滤波消除噪声

bila = cv2.bilateralFilter(mask, 10, 200, 200) # 双边滤波消除噪声 # 

高斯滤波

中值模糊

img = cv.medianBlur(gay_img, 7)  # 进行中值模糊,去噪点

edges = cv2.Canny(closing, 50, 100) # 边缘识别

图像变换

gay_img = cv.cvtColor(planets, cv.COLOR_BGRA2GRAY)#图像灰度化
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)#转换为HSV空间

透视变换

def PersTrans(frame,Center,frame_points): #透视变换,输入为图像
    rows,cols,channel = frame.shape
    src_points = np.float32([Center[0],Center[1],Center[2],Center[3]])
    dst_points = np.float32([[0,0],[cols-1,0],[0,rows-1],[cols-1,rows-1]])
    projective_martix = cv2.getPerspectiveTransform(src_points,dst_points)
    projective_image = cv2.warpPerspective(frame,projective_martix,(cols,rows))
    return projective_image,projective_martix

图像截取部分

cropped = img[30:440, 140:540]  #(上,下)(左,右)

你可能感兴趣的:(笔记,opencv,图像识别)