视觉学习(三)---opencv图像处理的一般过程

通过一些实践项目的练习,总结下图像处理的一般过程方法:

原始图–>灰度图–>高斯滤波,消除噪声–>二值图–>中值滤波,消除噪声–>膨胀处理–>数据处理(如:求得坐标,划线)–>图像融合

1. opencv学习

(1) 原图

w, h =image.shape[:2]   获取每帧图片的宽和高
image.shape[0], 图片垂直尺寸
image.shape[1], 图片水平尺寸
image.shape[2], 图片通道数

(2) 灰度图:cv2.cvtColor() 颜色空间转换

imgray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)  彩色图转灰度图

(3) cv2.GaussianBlur() 高斯滤波,线性平滑滤波,适用于消除高斯噪声

语法:cv2.GaussianBlur(src, ksize, sigmaX, sigmaY, borderType)-> dst

src 输入图像。
ksize 高斯内核大小。 ksize.width和ksize.height可以不同,但​​它们都必须为正数和奇数,也可以为零,然后根据sigmaX和sigmaY计算得出。
sigmaX X方向上的高斯核标准偏差。
sigmaY Y方向上的高斯核标准差;如果sigmaY为零,则将其设置为等于sigmaX;如果两个sigmas为零,则分别从ksize.width和ksize.height计算得出:
sigmaX=0.3×[(ksize.width-1)×0.5-1] +0.8 
sigmaY=0.3×[(ksize.height-1)×0.5-1]+0.8 
borderType是边界样式,该值决定了以何种方式处理边界。一般情况下,不需要考虑该值,直接采用默认值即可。在该函数中,sigmaY和borderType是可选参数。sigmaX是必选参数
dst 输出图像的大小和类型与src相同。

函数cv2.GaussianBlur() 的常用形式为:dst=cv2.GaussianBlur(src,ksize,0,0)

(4) cv2.adaptiveThreshold() 用于图像自适应阈值二值化

语法:dst = cv2.adaptiveThreshold(src, maxval, thresh_type, type, Block Size, C)

dst: 输出图
src: 输入图,只能输入单通道图像,通常来说为灰度图
maxval: 当像素值超过了阈值(或者小于阈值,根据type来决定),所赋予的值
thresh_type: 阈值的计算方法,包含以下2种类型:
    cv2.ADAPTIVE_THRESH_MEAN_C:  区域内均值
    cv2.ADAPTIVE_THRESH_GAUSSIAN_C: 区域内像素点加权和,权重为一个高斯窗口
type:二值化操作的类型,与固定阈值函数相同,用于控制参数2 maxval,包含以下5种类型:
    cv2.THRESH_BINARY: 黑白二值
    cv2.THRESH_BINARY_INV:黑白二值反转
    cv2.THRESH_TRUNC
    cv2.THRESH_TOZERO
    cv2.THRESH_TOZERO_INV
Block Size: 图片中区域的大小,取奇数	
C:阈值计算方法中的常数项

注:通过规定一个区域大小,比较处理像素点与区域大小里面像素点的平均值。阈值(或者其他特征)的大小关系确定这个像素点是属于黑或者白(如果是二值情况)。(经验之谈:寻找轮廓是针对白色物体的,一定要保证物体是白色,而背景是黑色,不然很多人在寻找轮廓时会找到图片最外面的一个框。其中红色和白色更容易检测到)

(5) cv2.medianBlur() 图像滤波:中值滤波,可对灰色图像和彩色图像使用,中值滤波对噪声的消除效果比线性滤波好,但是随着滤波核的增大,图像也会变模糊

语法:dst=cv2.medianBlur(src,ksize)

dst是返回值,表示进行中值滤波后得到的处理结果。
src 是需要处理的图像,即源图像
ksize 是滤波核的大小。滤波核大小是指在滤波处理过程中其邻域图像的高度和宽度。需要注意,核大小必须是比1大的奇数,比如3、5、7等

(6) cv2.dilate()函数对图片进行膨胀处处理

语法:cv2.dilate(img, kernel, iteration)
img – 目标图片
kernel – 进行操作的内核,默认为3×3的矩阵
iterations – 膨胀次数,默认为1
应用:
kernel = np.ones((4, 4), np.uint8)
img_dilate = cv2.dilate(img, kernel, iterations = 1)

(7) cv2.getRotationMatrix2D() 旋转矩阵,对图片使用该旋转矩阵,只是让图片绕着左上角进行旋转

语法: cv2.getRotationMatrix2D(center, angle, scale) 
center:旋转中心坐标,是一个元组参数(col, row)
angle:旋转角度,旋转方向,负号为逆时针,正号为顺时针
scale:旋转后图像相比原来的缩放比例,1为等比例缩放

(8) cv2.warpAffine 计算变换后的平移图像

dist = cv2.warpAffine(src, M, dsize)
src – 输入图像。
M – 变换矩阵。
dsize – 输出图像的大小。
2. 实例应用

通过像素点数量检测车位上是否有停车, 代码实现步骤如下:

# 处理视频图像
def  detect():
    # 为了使裁剪后的单个车位里面没有绘制的边框,需要在画车位框之前,把原图像复制一份
    imgCopy = img.copy()
        
    # 获得整每帧图片的宽和高
    img_w, img_h = img.shape[:2]  #shape是(w,h,c)
           
    # ==1== 转换灰度图,通过形态学处理来检测车位内有没有车
    imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  
    # ==2== 高斯滤波,卷积核3*3,沿x和y方向的卷积核的标准差为1
    imgGray = cv2.GaussianBlur(imgGray, (3,3), 1)
    
    # ==3== 二值图,自适应阈值方法
    imgThresh = cv2.adaptiveThreshold(imgGray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 101, 20)
    
    # ==4== 删除零散的白点,
    # 如果车位上有车,那么车位上的像素数量(白点)很多,如果没有车,车位框内基本没什么白点
    imgMedian = cv2.medianBlur(imgThresh, 5)  
    
    # ==5== 扩张白色部分,膨胀
    kernel = np.ones((3,3), np.uint8)  # 设置卷积核
    imgDilate = cv2.dilate(imgMedian, kernel, iterations=1) # 迭代次数为1
       
    #(4)绘制车位线矩形框
    w, h = 175,300  # 矩形框的宽和高
    
    # 遍历所有的矩形框坐标
    for pos in posList:
        # 得到旋转后的矩形的四个角坐标,传入原图,旋转参考点坐标,矩形框左上角坐标,框的宽w和高h,逆时针转4°(#根据实际情况修改)
        angle = recRota(imgDilate, pos[0], pos[1], pos[0], pos[1], w, h, -5, draw=False) # 裁剪的车位不绘制车位图  
        
        #(5)裁剪所有的车位框,由于我们的矩形是倾斜的,先要把矩形转正之后再裁剪
        # 变换矩阵,以每个矩形框的左上坐标为参考点,顺时针寻转4°,旋转后的图像大小不变
        rota_params = cv2.getRotationMatrix2D(angle[0], angle=-5, scale=1)  ##根据实际情况修改
        
        # 旋转整张帧图片,输入img图像,变换矩阵,指定输出图像大小
        rota_img = cv2.warpAffine(imgDilate, rota_params, (img_w, img_h))

        # 裁剪摆正了的矩形框,先指定高h,再指定宽w
        imgCrop = rota_img[pos[1]:pos[1]+h, pos[0]:pos[0]+w]

        # 显示裁剪出的图像
        # cv2.imshow('imgCrop', imgCrop)

        #(6)计算每个裁剪出的单个车位有多少个像素点
        count = cv2.countNonZero(imgCrop)
        
        # 将计数显示在矩形框上
        cv2.putText(imgCopy, str(count), (pos[0]+5, pos[1]+20), cv2.FONT_HERSHEY_COMPLEX, 0.8, (0,255,255), 2)

        #(7)确定车位上是否有车
        if count < 3000:  # 像素数量小于2500辆就是没有车
            color = (0,255,0)  # 没有车的话车位线就是绿色
            spacePark ="Empty" # 每检测到一个空车位,数量就加一 
        else:
            color = (0,0,255)  # 有车时车位线就是红色
            spacePark ="No empty"

        #(8)绘制所有车位的矩形框
        # 在复制后的图像上绘制车位框
        imgCopy = drawLine(imgCopy, angle, color, 3)

    # 绘制车位空闲标识
    # cv2.rectangle(imgCopy, (0,150), (200,210), (255,255,0), cv2.FILLED)
    cv2.rectangle(imgCopy, (0,0), (195,65), (255,255,255), 3)   #白色
    cv2.putText(imgCopy, spacePark, (15,40), cv2.FONT_HERSHEY_COMPLEX, 1, (255,0,255), 3)
    
    # cv2.imshow('img', imgCopy)
    # cv2.imshow('imgGray', imgGray) # 高斯滤波后
    # cv2.imshow('imgThresh', imgThresh)  # 二值化后
    # cv2.imshow('imgMedian', imgMedian)  # 模糊后
    # cv2.imshow('imgDilate', imgDilate)  # 膨胀
    
    return imgCopy

参考链接:停车场空余车位检测

你可能感兴趣的:(opencv,计算机视觉,opencv,图像处理)