OpenCV3计算机视觉Python语言实现(四)

1. Canny边缘检测

  OpenCV提供了Canny函数来识别边缘。Canny边缘检测算法有5个步骤:使用高斯滤波器对图像进行去噪、计算梯度、在边缘上使用非最大抑制(NMS)、在检测到的边缘上使用双阈值去除假阳性(false positive),最后还会分析所有的边缘及其之间的连接,以保留真正的边缘并消除不明显的边缘。

复制代码

import cv2
import numpy as np

img = cv2.imread("flower.jpg")
cv2.imwrite("canny.jpg", cv2.Canny(img, 200, 300))
cv2.imshow("image", img)
cv2.imshow("canny", cv2.imread("canny.jpg"))
cv2.waitKey()
cv2.destroyAllWindows()

复制代码

运行结果为:

 

2. 轮廓检测

  在计算机视觉中,轮廓检测不仅用来检测图像或者视频帧中物体的轮廓,而且还有其他操作与轮廓检测有关。如:计算多边形边界、形状逼近和计算感兴趣区域。这是与图像数据交互时的简单操作,因为NumPy中的矩形区域可以使用数组切片(slice)来定义。在物体检测(包括人脸)和物体跟踪时会大量使用。

复制代码

import cv2
import numpy as np

img = np.zeros((200, 200), dtype = np.uint8)   # 创建一个200x200大小的黑色空白图像,
img[50:150, 50:150] = 255                      # 在图像的中央放置一个白色方块

ret, thresh = cv2.threshold(img, 127, 255, 0)  #对图像进行二值化操作
image, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)  # 寻找轮廓
color = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)  # 颜色空间转换
img = cv2.drawContours(color, contours, -1, (0, 255, 0), 2)  # 画出轮廓,-1,表示所有轮廓,画笔颜色为(0, 255, 0),即Green,粗细为3
cv2.imshow("contours",color)
cv2.waitKey()
cv2.destroyAllWindows()

复制代码

  findContours()函数有三个参数:输入图像、层次类型和轮廓逼近方法。
  这个函数会修改输入图像,因此建议使用原始图像的一份拷贝(如:通过img.copy()来作为输入图像)。
  由函数返回的层次树相当重要:cv2.RETR_TREE参数会得到图像中轮廓的整体层次结构,以此来建立轮廓之间的“关系”。如果只想得到最外面的轮廓,可使用cv2.RETR_EXTERNAL。这对消除包含在其他轮廓中的轮廓很有用(如在大多数情形下,不需要检测一个目标包含在另一个与之相同的目标里面)
  findContours()函数有三个返回值:修改后的图像、图像的轮廓以及它们的层次。使用轮廓来画出图像的彩色版本(即把轮廓画成绿色),并显示出来。
  cv2.threshold()简单阈值
  这个函数有四个参数,第一个原图像,第二个进行分类的阈值,第三个是高于(低于)阈值时赋予的新值,第四个是一个方法选择参数,常用的有: 
    cv2.THRESH_BINARY(黑白二值) 
    cv2.THRESH_BINARY_INV(黑白二值反转) 
    cv2.THRESH_TRUNC (得到的图像为多像素值) 
    cv2.THRESH_TOZERO 
    cv2.THRESH_TOZERO_INV 
   该函数有两个返回值,第一个retVal(得到的阈值(在后面一个方法中会用到)),第二个就是阈值化后的图像。
   cvCvtColor(...)是Opencv里的颜色空间转换函数,可以实现RGB颜色向HSV,HSI等颜色空间的转换,也可以转换为灰度图像。参数CV_RGB2GRAY是RGB到gray。参数 CV_GRAY2RGB是gray到RGB.处理结果是彩色的,则转灰色就是了
 

运行结果为:

 3. 边界框、最小矩形区域和最小闭圆的轮廓

  可用OpenCV的cv2.findContours函数找到不规则的、歪斜的以及旋转的形状。现实的应用会对目标的边界框、最小矩形面积、最小闭圆特别感兴趣。

  3.1 绘制矩形

  函数:cv2.rectangle(img,(380,0),(511,111),(255,0,0),3),需要确定的就是矩形的两个点(左上角与右下角),颜色,线的类型(不设置就默认)

复制代码

import cv2
import numpy as np
from matplotlib import pyplot as plt
img = np.zeros((512,512,3),np.uint8)  #生成一个空彩色图像
cv2.rectangle(img,(20,20),(411,411),(55,255,155),5)
plt.imshow(img,'brg')
plt.show()

复制代码

 

复制代码

import cv2
import numpy as np

img = cv2.pyrDown(cv2.imread("hammer.jpg", cv2.IMREAD_UNCHANGED))
ret, thresh = cv2.threshold(cv2.cvtColor(img.copy(), cv2.COLOR_BGR2GRAY), 127, 255, cv2.THRESH_BINARY)
image, contours, hier = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

for c in contours:
    # find bounding box coordinates
    # 现计算出一个简单的边界框
    x, y, w, h = cv2.boundingRect(c)   # 将轮廓信息转换成(x, y)坐标,并加上矩形的高度和宽度
    cv2.rectangle(img, (x,y), (x+w, y+h), (0, 255, 0), 2)  # 画出矩形

    # find minimum area
    # 计算包围目标的最小矩形区域
    rect = cv2.minAreaRect(c)
    # calculate coordinate of the minimum area rectangle
    box = cv2.boxPoints(rect)
    # normalize coordinates to integers
    box =np.int0(box)
    # 注:OpenCV没有函数能直接从轮廓信息中计算出最小矩形顶点的坐标。所以需要计算出最小矩形区域,
    # 然后计算这个矩形的顶点。由于计算出来的顶点坐标是浮点型,但是所得像素的坐标值是整数(不能获取像素的一部分),
    # 所以需要做一个转换
    # draw contours
    cv2.drawContours(img, [box], 0, (0, 0, 255), 3)  # 画出该矩形

    # calculate center and radius of minimum enclosing circle
    (x, y), radius = cv2.minEnclosingCircle(c)  # 会返回一个二元组,第一个元素为圆心的坐标组成的元组,第二个元素为圆的半径值。
    # cast to integers
    center = (int(x), int(y))
    radius = int(radius)
    # draw the circle
    img = cv2.circle(img, center, radius, (0, 255, 0), 2)

cv2.drawContours(img, contours, -1, (255, 0, 0), 1)
cv2.imshow("contours", img)
cv2.waitKey()
cv2.destroyAllWindows()

复制代码

 运行结果为:

  在导入模块后,加载图像,然后在源图像的灰度图像上执行一个二值化操作。这样做之后,可在这个灰度图像上执行所有计算轮廓的操作,但在源图像上可利用色彩信息来画这些轮廓。

  cv2.drawContours(img, [box], 0, (0, 0, 255), 3):首先,该函数与所有绘图函数一样,它会修改源图像。其次,该函数的第二个参数接收一个保存着轮廓的数组,从而可以在一次操作中绘制一系列的轮廓。因此如果只有一组点来表示多边形轮廓,就需要把这组点放到一个数组里。该函数的第三个参数是要绘制的轮廓数组的索引:-1表示绘制所有的轮廓,否则只会绘制轮廓数组里指定的轮廓。大多数绘图函数把绘图的颜色和密度(thickness)放在最后两个参数里。

  函数介绍:

  cv2.imread():读入图片,共两个参数,第一个参数为要读入的图片文件名,第二个参数为如何读取图片,包括cv2.IMREAD_COLOR:读入一副彩色图片;cv2.IMREAD_GRAYSCALE:以灰度模式读入图片;cv2.IMREAD_UNCHANGED:读入一幅图片,并包括其alpha通道。cv2.imread('flower.jpg',0)表示已灰度模式读入

  cv2.imshow():创建一个窗口显示图片,共两个参数,第一个参数表示窗口名字,可以创建多个窗口中,但是每个窗口不能重名;第二个参数是读入的图片。

  cv2.waitKey():键盘绑定函数,共一个参数,表示等待毫秒数,将等待特定的几毫秒,看键盘是否有输入,返回值为ASCII值。如果其参数为0,则表示无限期的等待键盘输入。

  cv2.destroyAllWindows():删除建立的全部窗口

  cv2.destroyWindows():删除指定的窗口。

  cv2.imwrite():保存图片,共两个参数,第一个为保存文件名,第二个为读入图片

  Opencv中可以通过函数cv2.pyrDown()和cv2.pyrUp()来构建金字塔。

  函数cv2.pyrDown()是从一个高分辨率图像变成低分辨率图像的。cv2.pyrDown()函数接受3个参数:

  • tmp: 当前图像,初始化为原图像 src 。
  • dst: 目的图像( 显示图像,为输入图像的一半)
  • Size( tmp.cols/2, tmp.rows/2 ) :目的图像大小, 既然我们是向下采样

4. 凸轮廓与Douglas-Peucker算法

  大多数处理轮廓的时候,物体的形状(包括凸形状)都是变化多样的。凸形状内部的任意两点之间的连线都在该形状里面。

  cv2.approxPloyDP是一个OpenCV函数,它用来计算近似的多边形框。该函数有三个参数:

  第一个参数为“轮廓”;

  第二个参数为“ε值”,它表示源轮廓与近似多边形的最大差值(这个值越小,近似多边形与源轮廓越接近);

  第三个参数为“布尔标记”,它表示这个多边形是否闭合。

  ε值对获取有用的轮廓非常重要。是为所得到的近似多边形周长与源轮廓周长之间的最大差值,这个差值越小,近似多边形与源轮廓就越相似。

  可通过OpenCV的cv2.arcLength函数来得到轮廓的周长信息。

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

  可通过OpenCV来有效地计算一个近似多边形,多边形周长与源轮廓周长之比就为ε。

  为了计算凸形状,需要用OpenCV的cv2.convexHull函数来获取处理过的轮廓信息,代码为:

hull = cv2.convexHull(cnt)

5. 直线和圆检测

  Hough变换是直线和形状检测背后的理论基础。

  5.1 绘制直线  

  函数为:cv2.line(img,Point pt1,Point pt2,color,thickness=1,line_type=8 shift=0) 

  有值的代表有默认值,不用给也行。可以看到这个函数主要接受参数为两个点的坐标,线的颜色(彩色图像的话颜色就是一个1*3的数组)

复制代码

import cv2
import numpy as np
from matplotlib import pyplot as plt
img = np.zeros((512,512),np.uint8)#生成一个空灰度图像
cv2.line(img,(0,0),(511,511),255,5)
plt.imshow(img,'gray')
plt.show()

复制代码

 

  

复制代码

import cv2
import numpy as np
from matplotlib import pyplot as plt
img = np.zeros((512,512,3),np.uint8)#生成一个空彩色图像
cv2.line(img,(0,0),(511,511),(0,255,0),5)
plt.imshow(img,'brg')
plt.show()

复制代码

 

  5.2 直线检测

    直线检测可通过HoughLines和HoughLinesP函数来完成,它们仅有的差别是:第一个函数使用标准的Hough变换,第二个函数使用概率Hough变换。HoughLinesP函数之所以成为概率版本的Hough变换是因为它只通过分析点的子集并估计这些点都属于一条直线的概率,这是标准Hough变换的优化版本,该函数的计算代价会少一些,执行会变得更快。

复制代码

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.HoughLinesP(edges, 1, np.pi/180, 100, minLineLength, maxLineGap)

for x1, y1, x2, y2 in lines[0]:
    cv2.line(img, (x1, y1), (x2, y2), (0, 255, 0), 2)

cv2.imshow("edges", edges)
cv2.imshow("lines", img)
cv2.waitKey()
cv2.destroyAllWindows()

复制代码

    HoughLines函数会接收一个由Canny边缘检测滤波器处理过的单通道二值图像,不一定需要Canny滤波器,但是一个经过去噪并只有边缘的图像当作Hough变换的输入会很不错。

    HoughLinesP的参数:

    需要处理的参数;

    线段的几何表示rho和theta,一般分别取1和np.pi/180;

    阈值,低于该阈值的直线会被忽略,Hough变换可以理解为投票箱和投票数之间的关系,每一个投票箱代表一个直线,投票数达到阈值的直线会被保留,其他的会被删除。

    minLineLength和maxLineGap 

   5.3 绘制圆  

  绘制圆形只需要确定圆心与半径,函数: cv2.circle (img,(380,0),63,(255,0,0),3),

复制代码

import cv2
import numpy as np
from matplotlib import pyplot as plt
img = np.zeros((512,512,3),np.uint8)#生成一个空彩色图像
cv2.circle(img,(100,100),50,(55,255,155),5)
plt.imshow(img,'brg')
plt.show()

复制代码

   5.4 圆检测

    OpenCV的HoughCircles函数可用来检测圆,它与使用HoughLines函数类似。像用来决定删除或保留直线的两个参数minLineLength和maxLineGap一样,HoughCircles有一个圆心间的最小距离和圆的最小及最大半径。

复制代码

import cv2
import numpy as np

planets = cv2.imread("planet_glow.jpg")
gray_img = cv2.cvtColor(planets, cv2.COLOR_BGR2GRAY)
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,:]:
    # draw the outer circle
    cv2.circle(planets, (i[0], i[1]), i[2],(0, 255, 0),2)
    # draw the center of the circle
    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()

复制代码

运行结果为:

  

  5.5 绘制椭圆

  椭圆涉及到长轴短轴,椭圆圆心,旋转角度等。

     

复制代码

import cv2
import numpy as np
from matplotlib import pyplot as plt
img = np.zeros((512,512,3),np.uint8)#生成一个空彩色图像
cv2.ellipse(img,(256,256),(150,100),0,0,180,250,-1)
#注意最后一个参数-1,表示对图像进行填充,默认是不填充的,如果去掉,只有椭圆轮廓了
plt.imshow(img,'brg')
plt.show()

复制代码

6. 检测其他形状

  Hough变换能检测的形状仅限于圆,前面提到过检测任何形状的方法,特别是用approxPloyDP函数来检测,该函数提供多边形的近似,所以如果你的图像有多边形,再结合cv2.findContours函数和cv2.approxPloyDP函数,就能相当准确地检测出来。

OpenCV 3计算机视觉 Python语言实现(第二版)(含示例代码) 编辑推荐 OpenCV 3是一种*先进的计算机视觉库,它提供了很多图像和视频处理操作,以及一些代表计算机视觉未来发展方向的功能,如人脸识别或目标跟踪。学习计算机视觉算法、模型和OpenCV API的基本概念之后,可以开发各种现实生活中的应用程序(如安全和监控方面的应用程序)。 本书从图像处理的基本操作出发,带你开启先进计算机视觉的探索之旅。计算机视觉是一个快速发展的学科,与其相关的现实应用也呈爆炸性增长,本书的目的就是帮助计算机视觉领域的新手和想要了解全新的OpenCV 3.0.0的计算机视觉专家快速掌握基于PythonOpenCV计算机视觉开发的实用方法、技巧和*佳实践。 通过阅读本书,你将学到:   安装和熟练使用基于PythonOpenCV 3的API   掌握图像处理和视频分析的基础知识   在图像和视频中检测和识别目标   使用OpenCV检测和识别人脸   训练和使用自己的对象分类器   了解计算机视觉中的机器学习概念   使用OpenCV的人工神经网络来解决实际问题   开发现实生活中的计算机视觉应用 内容简介 OpenCV是开源、跨平台的计算机视觉库,由英特 尔公司发起并参与开发,在商业和研究领域中可以免费使用。本书介绍了如何通过Python来开发基于OpenCV 3.0的应用。作为当前非常流行的动态语言之一,Python不仅使用非常简单,而且功能强大。通过Python来学习OpenCV框架,可以让你很快理解计算机视觉的基本概念以及重要算法。 本书分8章来介绍计算机视觉的重要概念,所有的概念都融入了一些很有趣的项目。本书首先详细介绍了多个平台下基于PythonOpenCV安装,继而介绍了计算机视觉应用的基本操作,括图像文件的读取与显示,图像处理的基本操作(比如边缘检测等),深度估计与分割,人脸检测与识别,图像的检索,目标的检测与识别,目标跟踪,神经网络的手写体识别。可以这样说,本书是一本不可多得的采用OpenCV实践计算机视觉应用的好书。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值