OpenCV 3计算机视觉 python语言实现笔记(三)

#使用OpenCV 3处理图像


#高通滤波器
#高通滤波器(HPF)是检测图像的某个区域,然后根据图像与周围像素的亮度差值来
#提升(boost)该图像的亮度的滤波器。

#核(kernel)(滤波器矩阵):
[[0,-0.25,0],
 [-0.25,1,-0.25],
 [0,-0.25,0]]

#在计算完中央像素与周围邻近像素的亮度差值之和以后,如果亮度变化
#很大,中央像素的亮度会增加(反之则不会)。这在边缘检测上尤其有效。

#下面是一个高通滤波器的例子:
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]])

#注意:这些滤波器中的所有值加起来为0.

img = cv2.imread("../images/color1_small.jpg",0)
#卷积运算
k3 = ndimage.convolve(image,kernel_3x3)
k5 = ndimage.convolve(image,kernel_5x5)

#高斯模糊  (11,11)表示核的大小
blerred = cv2.GuassianBlur(image,(11,11),0)

g_hpf = image - blurred

cv2.imshow("3x3",k3)
cv2.imshow("5x5",k5)
cv2.imshow("g_hpf",g_hpf)
cv2.waitKey()
cv2.destroyAllWindows()


#==========================================================

#边缘检测

#OpenCV提供了许多边缘检测滤波函数,包括Laplacian(),Sobel()、
#以及Scharr()。这些滤波函数都会将飞边缘区域转为黑色,将边缘区域
#转为白色或其他饱和的颜色。
#但是这些函数很容易将噪声错误地识别为边缘,所以在其之前要先进行降噪(模糊处理)
#OpenCV提供了许多模糊滤波函数,包括blur()(简单的算术平均)、medianBlur()
#以及GaussianBlur()。

import cv2
import numpy
import scipy.interpolate

def strokeEdges(src,dst,blurKsize=7,edgeKsize=5):
    if blurKsize >= 3 :
        #模糊处理(降噪)
        blurredSrc = cv2.medianBlur(src,blurKsize)
        #将图像转为灰度图像
        graySrc = cv2.cvtColor(blurredSrc,cv2.COLOR_BGR2GRAY)
    else:
        graySrc = cv2.cv2Color(src,cv2.COLOR_BGR2GRAY)
    #边缘检测
    cv2.Laplacian(graySrc,cv2.CV_8U,graySrc,ksize=edgeKsize)
    #由于得到的结果是背景为黑色,边缘为白色。
    #我们在像素上操作,得到黑色的边缘,白色的背景
    #归一化(/255.0),并且用255. - graySrc得到取反的效果,左后乘原图的每一个通道即可
    normalizedInverseAlpha = (1.0/255.0) * (255.0 - graySrc)
    #将原图通道分离
    channels = cv2.split(src)
    #乘以原图的每个通道以便能将边缘变黑
    for channel in channels:
        channel[:] = channel * normalizedInverseAlpha
    #将通道合并
    cv2.merge(channel,dst)
    

    
#==========================================================
#定制内核做卷积

#OpenCV提供了一个非常通用的filter2D()函数,它运用由用户指定的任意和或卷积矩阵,进行卷积计算

#定义一个高通滤波器,然图像锐化
kernel = numpy.array([[-1,-1,-1],
                      [-1, 9,-1],
                      [-1,-1,-1]])
#在源图像上使用卷积矩阵得到目标图像dst
cv2.filter2D(src,-1,kernel,dst)
#第二个参数指定了目标图像每个通道的位深度(比如,cv2.CV_8U)表示每个通道为8位


#创建滤波器基类
class VConvolutionFilter(object):
    def __init__(self,kernel):
        self._kernel = kernel
    #卷积计算
    def apply(self,src,dsr):
        cv2.filter2D(src,-1,self._kernel,dst)
#创建锐化滤波器
class SharpenFilter(VConvolutionFilter):
    #半径为一个像素
    def __init__(self):
        kernel = numpy.array([[-1,-1,-1],
                              [-1, 9,-1],
                              [-1,-1,-1]])
        VConvolutionFilter.__init__(self,kernel)
#注意权重加起来为1,如果不想改变图像的亮度就应该这样。
#稍微修改一下锐化核,使得权重加起来为0,就会得到一个边缘检测核

#创建边缘检测滤波器
class FindEdgesFilter(VConvolutionFilter):
    def __init__(self):
        kernel = numpy.array([[-1,-1,-1],
                              [-1, 9,-1],
                              [-1,-1,-1]]) 
        VConvolutionFilter.__init__(self,kernel)

#创建模糊滤波器
#为了达到模糊效果,通常权重和应该为1,而且邻近像素的权重全为正
#下面实现一个简单的邻近平均滤波器
class BlurFilter(VConvolutionFilter):
    def __init__(self):
        kernel = numpy.array([[0.04,0.04,0.04,0.04,0.04],
                              [0.04,0.04,0.04,0.04,0.04],
                              [0.04,0.04,0.04,0.04,0.04],
                              [0.04,0.04,0.04,0.04,0.04],
                              [0.04,0.04,0.04,0.04,0.04]])
        VConvolutionFilter.__init__(self,kernel)
        

    
#锐化、边缘检测以及模糊等滤波器都使用了高度对称的核。
#但是不对称的核也还会产生一些有趣的效果。

#浮雕(embossed)滤波器
class EmbossFilter(VConvolutionFilter):
    def __init__(self):
        kernel = numpy.array([[-2,-1, 0],
                              [-1, 1, 1],
                              [ 0, 1, 2]])  
        VConvolutionFilter.__init__(self,kernel)
        

        
        
#============================================================
#Canddy边缘检测

#OpenCV提供了一个非常方便的Canny函数,一行代码实现边缘检测
Import cv2
import numpy as np

img = cv2.imread("../images/statue_small.jpg",0)
cv2.imwriter("canny.jpg",cv2.Canny(img,200,300)) #200位最小阈值,300位最大阈值
cv2.imshow("canny",cv2.imread("canny.jpg"))
cv2.waitKey()
cv2.destroyAllWindows()


#============================================================
#轮廓检测

import cv2
import numpy as np

#创建一张黑色的图像
img = np.zeros((200,200),dtype=np.uint8)
#将图像的中间变成白色
img[50:150,50:150] = 255

#对图像进行二值化操作,最小阈值为127,最大阈值为255
#将大于127的像素变成255,否则变为0.
ret, thresh = cv2.threshold(img,127,255,0)
#获取图像的轮廓
image, contours, hierarchy = cv2.findCountours(thresh,
                                               cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
#源灰度图像转换为彩色图像
color = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)
#在源图上画出轮廓
#参数分别表示:源图(彩色)、轮廓list、-1表示画出所有的轮廓、颜色(绿色)、轮廓宽度
img = cv2.drawContours(color,contours,-1,(0,255,0),2)

#显示图像
cv2.imshow("contours",color)
cv2.waitKey()
cv2.destroyAllWindows()


#边界框、最小矩形区域和最小闭圆的轮廓
#同上面一样,首先得到灰度图像,对灰度图像进行二值化,然后获取轮廓list
import cv2
import numpy as np


#purDown()对图像进行下采样,得到的图像的宽和高都是源图的1/2
img = cv2.pyrDown(cv2.imread("hammer.jpg",cv2.IMREAD_UNCHAGED))

#二值化,由于只操作会改变源图,所以使用copy操作
ret, thresh = cv2.threshold(cv2.cvtColor(image.copy(),cv2.COLOR_BGR2GRAY),
                           127,255,0)
#获取轮廓
image, contours, hier = cv2.findContours(thresh,cv2.RETR_EXTERNAL,
                                        cv2.CHAIN_APPROX_SIMPLE)

#分别得到包含轮廓的矩形边框,可以有旋转的矩形边框和圆形边框
for c in contours:
    #获取矩形边框(绿色)
    x,y,w,h = cv2.boundingRect(c)
    cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
    
    #获取有旋转的矩形边框
    rect = cv2.minAreaRect(c)
    #计算顶点坐标
    box = cv2.boxPoint(rect)
    #将顶点坐标转换为整形
    box = np.int0(box)
    #画边框(红色)
    cv2.drawContours(img,[box],0,(0,0,255),3)
    
    #获取圆形边框
    #计算圆的中心点坐标和半径
    (x,y),radius = cv2.minEnclosingCircle(c)
    #坐标和半径转换为整形
    center = (int(x),int(y))
    radius = int(radius)
    #画圆(绿色)
    cv2.circle(img,center,radius,(0,255,0),2)

#图上的3种边框画完了,最后在画出轮廓即可
cv2.drawContours(img,contours,-1,(0,255,0),2)
cv2.imshow("contours",img)

#画轮廓的近似的多边形和凸包

#凸包内的任意两点的连线都在该形状里面

#cv2.approxPloyDP()是一个OpenCV函数,它用来计算近似的多边形框。
#函数参数:轮廓、ε值(表示源轮廓周长与近似多边形的周长最大差值)、是否闭合

epsilon = 0.01 * cv2.arcLength(cnt,True)
approx = cv2.approxPloyDP(cnt,epsilon,True)

#使用cv2.convexHull()函数获取凸包
hull = cv2.convexHull(cnt)


#================================================================
#直线和圆检测

#直线检测
#通过HoughLines()和HoughLinesP()函数来完成

import cv2
import numpy as np

#获取边缘
img = cv2.imread('lines.jpg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray,50,120)
#设置直线的最小长度和最大距离
minLineLength = 20
maxLineGap = 5
lines = cv2.HougLinesP(edgs,1,np.pi/180,100,minLineLength,maxLineGap)
#x1,y1,x2,y2表示直线起始点和终点的坐标
for x1,y1,x2,y2 in lines[0]:
    cv2.line(img,(x1,y1),(x2,y2),(0,255,0),2)
    
cv2.inshow("edges",edges)
cv2.imshow("lines",img)
cv2.waitKey()
cv2.destroyAllWindows()


#================================================================
#圆检测

#OpenCV的HoughCircles函数可用来检测圆,它与使用HoughLines函数类似。
#参数包括圆心间的最小距离和圆的最小及最大半径
import cv2
import numpy as np

planets = cv2.imread('planet_glow.jpg')
gray_img = cv2.cvtColor(planets,cv2.COLOR_BGR2GRAY)
#模糊处理(去噪),ksize = 5
img = cv2.medianBlur(gray_img,5)
#保存彩色图像,我们对灰度图像进行处理
cimg = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)
#在灰度图像中检测圆
circles = cv2.HoughCircles(img,cv2.HOUGH_GRADIENT,1,120,
                           param1=100,param2=30,minRadius=0,
                           maxRadius=0)
#四舍五入取整
circles = np.uint16(np.around(circles))
  
for i in circles[0,:]:
    #画外圈
    cv2.circle(planets,(i[0],i[1]),i[2],(0,255,0),2)
    #画圆心
    cv2.circle(planets,(i[0],i[1]),2,(0,0,255),3)
    
cv2.imwrite("planets_circles.jpg",planets)
cv2.imshow("HoughCircles",planets)
cv2.waitKey()
cv2.destroyAllWindows()


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值