opencv图像处理——(1)

opencv图像处理——(1)

文章目录

  • opencv图像处理——(1)
    • 一、几个算子
      • 1. Sobel运算
      • 2.Scharr算子
      • 3.laplacian算子
      • 4.三个算子的比较
    • 二、Canny 边缘检测
      • 1. 最大值抑制
      • 2. 双阈值法
      • 3. code
    • 三、图像金字塔
      • 1. 高斯金字塔
      • 2. 拉普拉斯金字塔
        • 解决方案

一、几个算子

1. Sobel运算

边缘位置产生梯度
边缘检测

右减左,下减上
通常情况下,图像的深度设置为-1
水平方向和竖直方向分开计算,直接整体计算效果不好

# sobel 算子
sobelx=cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)#水平方向取1,0
sobelx=cv2.convertScaleAbs(sobelx)#sobel算子的水平方向是右减左,为负数的地方时都取0,避免左边像素点比右边高时出现黑色的情况,所以对所求的差值去绝对值进行处理
sobely=cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)#垂直方向取0,1
sobely=cv2.convertScaleAbs(sobely)
sobelxy1=cv2.add(sobelx,sobely)#直接相加,简单的相加
sobelxy2=cv2.addWeighted(sobelx,0.5,sobely,0.5,0)#带权重的相加,需要定义最后的gamma值,具体什么意思还不太明白
plt.subplot(221),plt.imshow(sobelx)
plt.subplot(222),plt.imshow(sobely)
plt.subplot(223),plt.imshow(sobelxy1)
plt.subplot(224),plt.imshow(sobelxy2)

opencv图像处理——(1)_第1张图片

2.Scharr算子

类似sobel,更加敏感

# scharr算子
scharrx=cv2.Scharr(img,cv2.CV_64F,1,0)#水平方向取1,0
scharrx=cv2.convertScaleAbs(scharrx)#sobel算子的水平方向是右减左,为负数的地方时都取0,避免左边像素点比右边高时出现黑色的情况,所以对所求的差值去绝对值进行处理
scharry=cv2.Scharr(img,cv2.CV_64F,0,1)#垂直方向取0,1
scharry=cv2.convertScaleAbs(scharry)
scharrxy1=cv2.add(scharrx,scharry)#直接相加,简单的相加
scharrxy2=cv2.addWeighted(scharrx,0.5,scharry,0.5,0)#带权重的相加,需要定义最后的gamma值,具体什么意思还不太明白
plt.subplot(221),plt.imshow(scharrx)
plt.subplot(222),plt.imshow(scharry)
plt.subplot(223),plt.imshow(scharrxy1)
plt.subplot(224),plt.imshow(scharrxy2)

opencv图像处理——(1)_第2张图片

3.laplacian算子

二阶,不需要分开做
对噪音点敏感,一般和其他方法融合使用

# 拉普拉斯算子
laplacian=cv2.Laplacian(img,cv2.CV_64F)
laplacian=cv2.convertScaleAbs(laplacian)

4.三个算子的比较

plt.subplot(131),plt.imshow(sobelxy2)
plt.subplot(132),plt.imshow(scharrxy2)
plt.subplot(133),plt.imshow(laplacian)

二、Canny 边缘检测

1. 最大值抑制

根据box的画出的面积计算IoU进行衡量,找到最佳的box

2. 双阈值法

如果梯度值小于设置的min,直接舍弃
梯度值大于设置的max,将其处理为边界
在者之间的点,如果和边界相连,保留,否则舍弃

3. code

## canny边缘检测
canny1=cv2.Canny(img,80,100)
canny2=cv2.Canny(img,80,150)
res=np.hstack((canny1,canny2))
plt.imshow(res)

opencv图像处理——(1)_第3张图片
min越大,要求越高
max越小,要求越高

三、图像金字塔

对金字塔先进行下采样再进行上采样,得到的图像是原图像吗??
当然不是,因为在进行下采样将样本的特征提取之后,再次进行上采样的时候时进行0填补,会让图片变得模糊

1. 高斯金字塔

# 高斯金字塔
def Gaussianpyr_down(img,level):
    r=(level//4)+1
    
    result= []
    result.append(img)
    # 下采样
    for i in range(1,level+1):
        result.append(cv2.pyrDown(result[i-1]))
    for i in range(level+1):
        plt.subplot(r,4,i+1),plt.imshow(result[i])

def Gaussianpyr_up(img,level):
    r=(level//4)+1
    
    result= []
    result.append(img)
    # 上采样
    for i in range(1,level+1):
        result.append(cv2.pyrUp(result[i-1]))
    for i in range(level+1):
        plt.subplot(r,4,i+1),plt.imshow(result[i])

img=cv2.imread('./test.png',cv2.IMREAD_GRAYSCALE)
Gaussianpyr_down(img,3)
plt.figure()
Gaussianpyr_up(img,3)

opencv图像处理——(1)_第4张图片

2. 拉普拉斯金字塔

注意:在拉普拉斯金字塔的过程中,一定要注意如果原图的像素点是奇数,在经过下采样和上采样以后,一定会出现原图无法与采样后的图片进行加减,因为在进行下采样的时候或删除偶数项的行,所以在下采样再进行上采样以后,两个不等大的矩阵是没法进行加减的

解决方案

在处理之前需要先判断图像的像素点个数,如果是奇数需要先进性填补或者进行删减。
注意:在进行图像填充的时候需要设置的参数必须是正整数,不可以设置为小数,因此只能偏向设置,一边只能设置为0

# 拉普拉斯金字塔
#L=G(origional)-Gaussion_up(Gaussion_down(origional))
def GSP_down(img,level):
    result= []
    result.append(img)
    # 下采样
    for i in range(1,level+1):
        result.append(cv2.pyrDown(result[i-1]))
    return result[level]

def GSP_up(img,level):
    result= []
    result.append(img)
    # 上采样
    for i in range(1,level+1):
        result.append(cv2.pyrUp(result[i-1]))
    return result[level]

def LP(img,level):
    r=(level//4)+1
    result= []
    if(img.shape[0]%2==0 and img.shape[1]%2==0):
        result.append(img)
        for i in range(1,level+1):    
            #result[i]的前一项存的是原图,
            result.append((result[i-1]-GSP_up(GSP_down(result[i-1],1),1)))
    elif(img.shape[0]%2!=0 and img.shape[1]%2==0):#横向为奇数
        # 先对像素点进行填充        
        top_size,bottom_size,left_size,right_size=(0,0,1,0)
        temp=cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_REFLECT_101)
        result.append(temp)
        for i in range(1,level+1):    
            #result[i]的前一项存的是原图,
            result.append((result[i-1]-GSP_up(GSP_down(result[i-1],1),1)))
    elif(img.shape[0]%2==0 and img.shape[1]%2!=0):#纵向为奇数
        # 先对像素点进行填充        
        top_size,bottom_size,left_size,right_size=(1,0,0,0)
        temp=cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_REFLECT_101)
        result.append(temp)
        for i in range(1,level+1):    
            #result[i]的前一项存的是原图,
            result.append((result[i-1]-GSP_up(GSP_down(result[i-1],1),1)))
    else:# 横向纵向都为奇数        
        top_size,bottom_size,left_size,right_size=(1,0,1,0)
        temp=cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_REFLECT_101)
        result.append(temp)
        for i in range(1,level+1):    
            #result[i]的前一项存的是原图,
            result.append((result[i-1]-GSP_up(GSP_down(result[i-1],1),1)))
    for i in range(level+1):
        plt.subplot(r,4,i+1),plt.imshow(result[i])

LP(img,3)

opencv图像处理——(1)_第5张图片
得嘞,是有希望的一天~

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