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函数,就能相当准确地检测出来。
OpenCV3计算机视觉Python语言实现笔记(四)的更多相关文章
- OpenCV3计算机视觉Python语言实现笔记(三)
一.使用OpenCV处理图像 1.不同颜色空间的转换 OpenCV中有数百种关于在不同色彩空间之间转换的方法.当前,在计算机视觉中有三种常用的色彩空间:灰度.BGR以及HSV(Hue, Saturat ...
- OpenCV3计算机视觉Python语言实现笔记(二)
1. 图像与原始字节之间的转换 从概念上讲,一个字节能表示0到255的整数.目前,对于多有的实时图像应用而言,虽然有其他的表示形式,但一个像素通常由每个通道的一个字节表示. 一个OpenCV图像是.a ...
- OpenCV3计算机视觉Python语言实现笔记(五)
图像的几何变换主要包括:平移.扩大与缩小.旋转.仿射.透视等等.图像变换是建立在矩阵运算基础上的,通过矩阵运算可以很快的找到对应关系. 1. 图像的平移 图像的平移,沿着x方向tx距离,y方向ty距离 ...
- OpenCV3计算机视觉Python语言实现笔记(一)
Python3下OpenCV的安装 :http://blog.csdn.net/lwplwf/article/details/61616493 1. 读/写图像文件 OpenCV的imread()函数 ...
- 《OpenCV3 计算机视觉--Python语言实现 第二版》源代码及纠错
1.源代码下载地址 <OpenCV3 计算机视觉--Python语言实现 第二版>由我们翻译,英文书名<Learning OpenCV3 Computer Vision with P ...
- Go语言学习笔记四: 运算符
Go语言学习笔记四: 运算符 这章知识好无聊呀,本来想跨过去,但没准有初学者要学,还是写写吧. 运算符种类 与你预期的一样,Go的特点就是啥都有,爱用哪个用哪个,所以市面上的运算符基本都有. 算术运算 ...
- 学习CV:《OpenCV 3计算机视觉Python语言实现第2版》中文PDF+英文PDF+代码
理解与计算机视觉相关的算法.模型以及OpenCV 3 API背后的基本概念,有助于开发现实世界中的各种应用程序(比如:安全和监视领域的工具). OpenCV 3是一种先进的计算机视觉库,可以用于各种图 ...
- opencv3计算机视觉+Python(四)
使用分水岭和GrabCut算法进行物体分割 用GrabCut算法进行图像分割 在OpenCV中,实现了grabcut分割算法,该算法可以方便的分割出前景图像,操作简单,而且分割的效果很好.算法的原理参 ...
- python语言学习笔记整理
什么是程序? 程序等于数据结构加算法,那么数据结构是一个静态的东西,算法是一个动态的东西,我们用一个新的语言编写这个程序,我们要考虑到语言也主要由数据结构和算法相关的东西,或静态或动态的东西来构成,所 ...
随机推荐
- agc002E - Candy Piles(博弈论)
题意 题目链接 Sol Orz SovitPower #include<bits/stdc++.h> #define Pair pair<int, double> #defin ...
- Django引入静态文件
在HTML文件中引入方式: 简单引入一个bootstrap中的内敛表单,效果图如下:
- Windchill_IBA属性
IBA属性:也可以称为软属性,创建IBA属性后并不会改变已有对象的数据库表结构,IBA的属性名和属性值由专门的表存放. StringDefinition表:字符串类型的IBA属性定义 :StringV ...
- LVS + nginx实现高性能精准负载均衡
- Android项目实战(四十一):游戏和视频类型应用 状态栏沉浸式效果
需求: 手机app ,当打游戏或者全屏看视频的时候会发现这时候手机顶部的状态栏是不显示的,当我们从手机顶端向下进行滑动或手机底端向上滑动的时候,状态栏会显示出来,如果短暂的几秒时间没有操作的话,状态 ...
- Spring Data Redis 让 NoSQL 快如闪电 (1)
[编者按]本文作者为 Xinyu Liu,详细介绍了 Redis 的特性,并辅之以丰富的用例.在本文的第一部分,将重点概述 Redis 的方方面面.文章系国内 ITOM 管理平台 OneAPM 编译呈 ...
- SQL 中常用存储过程xp_cmdshell运行cmd命令
目的: 使用SQL语句,在D盘创建一个文件夹myfile 首先查询系统配置 SELECT * FROM sys.configurations WHERE name='xp_cmdshell' OR n ...
- Linux进程调度策略的发展和演变--Linux进程的管理与调度(十六)
1 前言 1.1 进程调度 内存中保存了对每个进程的唯一描述, 并通过若干结构与其他进程连接起来. 调度器面对的情形就是这样, 其任务是在程序之间共享CPU时间, 创造并行执行的错觉, 该任务分为两个 ...
- window.location.href刷新页面
刷新当前页 window.location.href=window.location.href; 或者 window.location.href="当前URL",例如 window ...
- mysql 中的内置函数
一.字符串函数 select concat(name,"age is",age) from users; insert(str,x,y,insert)//将字符串x位置开始y个位 ...