【笔记】OpenCV3 图形处理-边缘检测(三)

  • 计算机视觉中有三种常用色彩空间
    • 灰度  去掉彩色信息,转换为灰阶
    • BGR  蓝绿红的色彩空间,每个像素点用一个三维数组来表示
    • HSV  H 色调、S 饱和度、V 程度

 

  • 高通滤波器

检测图像的某个区域,根据像素与周围像素的亮度差值来提升该像素亮度的滤波器

计算完中央像素与周围临近像素后,如果亮度变化很大,中央像素会增加(相反不会),如果一个像素比它周围突出很多,就会提升他的亮度,这对边缘检测就比较有效了。。。

定义两个核,与图像卷积看看效果

import cv2
import numpy as np
from scipy import ndimage


kernel_3X3 = np.array([
    [-1,-1,-1],
    [-1, 8,-1],
    [-1,-1,-1]
])

kernel_5X5 = np.array([
    [-1, -1 ,-1, -1, -1],
    [-1,  1,  2,  1, -1],
    [-1,  2,  4,  2, -1],
    [-1,  1,  2,  1, -1],
    [-1, -1, -1, -1, -1]
])

将图片灰度读出,与自定义的核进行卷积,看下效果

img = cv2.imread("img/Lena.jpg",0)
cv2.imshow('img',img)
k3 = ndimage.convolve(img, kernel_3X3)
k5 = ndimage.convolve(img, kernel_5X5)
cv2.imshow('3X3',k3)
cv2.imshow('5X5',k5)

【笔记】OpenCV3 图形处理-边缘检测(三)_第1张图片

  • 低通滤波器 

检测图像的某个区域,在像素与周围像素的亮度差值小于一个特定值时,平衡该像素的亮度,它主要用于去噪与模糊

 

  • 另外的实现方式:对图像采用低通滤波器后,再与原图像计算差值,来实现
blurred = cv2.GaussianBlur(img, (11,11), 0)
cv2.imshow('blurred',blurred)
g_hpf = img - blurred
cv2.imshow('g_hpf',g_hpf)

看起来效果貌似好很多的样子哦。。。。

 

  • OpenCV还提供了其他的模糊函数:
    • blur()  算术平均
    • medinBlur()  去除数字化的视频噪声非常非常有效
    • GaussianBlur()

好像很高级的样子,用来试试。。

blurred = cv2.medianBlur(img,11)
cv2.imshow('blurred',blurred)

blurred = cv2.blur(img,(7,7))
cv2.imshow('blurred',blurred)

 

捣鼓了半天,主要还是想边缘检测。。。。

  • 边缘检测函数
    • Laplacian()
    • Sobel()
    • Scharr()
    • Canny

这些函数,都会将非边缘区域转换为黑色,边缘区域转换为白色或者其他饱和颜色

试试才知道效果。。。

  • Laplacian()   使用Laplacian之前,需要将图像转为灰度图
grayImg = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.Laplacian(grayImg,cv2.CV_8U,grayImg,ksize=5)
cv2.imshow('lap',grayImg)
转换前后

 

  • 将上面的操作配合起来一起使用

调用medianBlur()图片模糊去噪,再用Laplacian边缘检测,效果看起来貌似比直接边缘检测好很多

blurred = cv2.medianBlur(img,7)
grayImg = cv2.cvtColor(blurred, cv2.COLOR_BGR2GRAY)
cv2.Laplacian(grayImg,cv2.CV_8U,grayImg,ksize=5)
cv2.imshow('gray2',grayImg)

【笔记】OpenCV3 图形处理-边缘检测(三)_第2张图片

 

  • 继续,将图像归一化,与原图相乘,将边缘变黑
def storkeEdges(src, dst, blurKsize=7, edgeKsize=5):
    if blurKsize > 3:
        #模糊函数,去噪声,可减少blurKsize来调节性能
        blurredSrc = cv2.medianBlur(src, blurKsize)
        graySrc = cv2.cvtColor(blurredSrc, cv2.COLOR_BGR2GRAY)
    else:
        graySrc = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)

    # 边缘检测,产生明确的边缘线条
    cv2.Laplacian(graySrc, cv2.CV_8U, graySrc, ksize=edgeKsize)

    normalizedInverseAlpha = (1.0/255)*(255-graySrc)
    channels = cv2.split(src)
    for channel in channels:
        channel[:] = channel * normalizedInverseAlpha
    cv2.merge(channels, dst)
filters.storkeEdges(img,img)
cv2.imshow('after',img)

调用下看看效果,好黑。。。

 

  • Sobel()
def Sobel(src, ddepth, dx, dy, dst=None, ksize=None, scale=None, delta=None, borderType=None)

ddepth:图像的颜色深度  -1表示跟源图保持一致

dx,dy:表示x,y方向的差分阶数 取0或者1 

ksize: 核的大小,默认3

 

弄几个不同方向的试试水。。  0,1感觉还可以。。

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
sobx = cv2.Sobel(gray,cv2.CV_8U,1,0)
soby = cv2.Sobel(gray,cv2.CV_8U,0,1)
sob = cv2.Sobel(gray,-1,1,1)
cv2.imshow('sobelx',sobx)
cv2.imshow('sobely',soby)
cv2.imshow('sobel',sob)

 

 

  • Scharr()

参数跟Sobel差不多,核固定为3, dx dy不能同时为1或者0,比Sobel结果更精准

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

schx = cv2.Scharr(gray,-1,1,0)
schy = cv2.Scharr(gray,-1,0,1)

cv2.imshow('schx',schx)
cv2.imshow('schy',schy)

 

  • Canny()
def Canny(image, threshold1, threshold2, edges=None, apertureSize=None, L2gradient=None)

threshold1\threshold2: 低阈值,高阈值  低于阈值1的像素点或者高于阈值2的 不认为是边缘点

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

def doChange(x):
    positon = cv2.getTrackbarPos('trackbar','cany')
    canyimg = cv2.Canny(gray,positon,positon*2.5)
    cv2.imshow('cany', canyimg)

cv2.namedWindow('cany')
cv2.createTrackbar('trackbar','cany',1,100,doChange)

拖动来看不同点的效果

【笔记】OpenCV3 图形处理-边缘检测(三)_第3张图片【笔记】OpenCV3 图形处理-边缘检测(三)_第4张图片

 

你可能感兴趣的:(学习笔记,OpenCV)