www.2527.com_澳门新葡8455手机版_新京葡娱乐场网址_
做最好的网站

颜色捕捉和通道变换,OpenCV基本操作方法详解

2019-05-31 22:11 来源:未知

基本属性

本文主要介绍 OpenCV 中颜色通道相关的操作,以及图像的旋转和平移操作等。

转换

cv2.imread(文件名,属性) 读入图像

改变颜色通道

在 OpenCV 中,一共有超过 150 种改变颜色通道的方法,不过我们主要研究其中最重要的两个:BGR 和 Gray 的转换和 BGR 和 HSV 的转换。
转换颜色通道时,我们使用 cv2.cvtColor(input_img,flag) 这个函数,其中 flag 主要决定了转换的类型。BGR 到 Gray 的转换用的 flag 是 cv2.COLOR_BGR2GRAY,BGR 到 HSV 的转换用的 flag 是 cv2.COLOR_BGR2HSV。在 HSV 图像中,H 表示色调取值范围为 0 到 179,S 表示饱和度取值范围为 0 到 255,V 表示亮度取值范围为 0 到 255。
举个应用的例子,我们可以用改变颜色通道的方法去追踪物体:相比 BGR 颜色通道,HSV 可以更加容易得在一个范围内去表示一种颜色。所以,在追踪特定颜色的物体时,我们经常把 BGR 的颜色通道转换成 HSV 的通道,用摄像机捕捉一个蓝色瓶盖的过程如下:

  1. 得到摄像机的每一帧图像
  2. 把图像从 BGR 转换成 HSV
  3. 在 HSV 中过滤掉蓝色以外的所有其他颜色
  4. 最后提取出蓝色的物体,然后就可以用各种方法去追踪这个蓝色的物体了。
import cv2  
import numpy as np  

cap = cv2.VideoCapture(0)  

while(1):  

   # Take each frame  
   _, frame = cap.read()  

   # Convert BGR to HSV  
   hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)  

   # define range of blue color in HSV  
   lower_blue = np.array([110,50,50])  
   upper_blue = np.array([130,255,255])  

   # Threshold the HSV image to get only blue colors  
   mask = cv2.inRange(hsv, lower_green, upper_green)  

   # Bitwise-AND mask and original image  
   res = cv2.bitwise_and(frame,frame, mask= mask)  

   cv2.imshow('frame',frame)  
   cv2.imshow('mask',mask)  
   cv2.imshow('res',res)  
   k = cv2.waitKey(5) & 0xFF  
   if k == 27:  
       break  

cv2.destroyAllWindows()  

我们可以注意到,图像中有一些噪声,我们将会在以后的章节中除去这些噪声。这是物体追踪中最简单的方法,当我们学到轮廓检测等更有效的算法时,还可以在上面做更多有趣的事情。
最后还有一个问题,如何找到对应颜色的 HSV 范围?方法很简单,还是用 cv2.cvtColor() 这个函数:

>>> green = np.uint8([[[0,255,0 ]]])  
>>> hsv_green = cv2.cvtColor(green,cv2.COLOR_BGR2HSV)  
>>> print hsv_green  
[[[ 60 255 255]]]  

获得了 [60,255,255] 这个值后,我们可以把 [H-10,100,100,] 和[H 10,255,255]作为绿色的范围。当然,你也可以用其他的图像处理软件去获得这个值比如 GIMP 等。2. 图像的几何操作
当我们要缩放图像时,要用到 cv2.resize() 这个函数,缩放的比例可以在函数的参数中调整。同时,因为缩放图像需要对像素点进行处理,所以我们需要为缩放选择一个合适的插值函数 (就是告诉计算机放大的图像中那些多出来的像素点的取值是多少,缩小的图像中每个像素点的值该怎么取)。一般,缩小图像时会采用 cv2.INTER_AREA,放大图像时可以采用 cv2.INTER_CUBIC 或者 cv2.INTER_LINEAR,以下程序把原图放大了一倍:

import cv2  
import numpy as np  

img = cv2.imread('messi5.jpg')  

res = cv2.resize(img,None,fx=2, fy=2, interpolation = cv2.INTER_CUBIC)  

#OR  

height, width = img.shape[:2]  
res = cv2.resize(img,(2*width, 2*height), interpolation = cv2.INTER_CUBIC) 

如果我们要平移一幅图像,首先要生成一个转移矩阵,告诉计算机如何去平移这个图像
其中,表示了向右和向下平移的坐标量。
而且,这个转移矩阵要求是一个 Numpy 数组,数据类型是 float32,最后把这个数组传递给 cv2.warpAffine() 函数,实现平移。

import cv2  
import numpy as np  

img = cv2.imread('messi5.jpg',0)  
rows,cols = img.shape  

M = np.float32([[1,0,100],[0,1,50]])  
dst = cv2.warpAffine(img,M,(cols,rows))  

cv2.imshow('img',dst)  
cv2.waitKey(0)  
cv2.destroyAllWindows()  

需要注意的是 cv2.warpAffine() 函数的第三个参数表示输出图像的尺寸。
如果我们要旋转一幅图像,就需要为 OpenCV 构建一个关于旋转的转移矩阵:这个矩阵要说明旋转的角度,旋转的中心点和缩放比例
为了构建这样的转移矩阵,OpenCV 提供了一个 c2.getRotationMatrix2D() 这个函数,只要在这个函数中输入旋转中心点的坐标,旋转角度和缩放大小,函数就能返回一个转移矩阵:

img = cv2.imread('messi5.jpg',0)  
rows,cols = img.shape  

M = cv2.getRotationMatrix2D((cols/2,rows/2),90,1)  
dst = cv2.warpAffine(img,M,(cols,rows))  

在仿射变换中,要求所有在原图想中平行的直线在输出图像中也是平行的。因此,我们需要输入三个点在原图中的坐标和变换后的坐标,来形成仿射变换的转移矩阵。把这六个坐标输入到 cv2.getAffineTransform() 中,就能产生这个转移矩阵:

img = cv2.imread('drawing.png')  
rows,cols,ch = img.shape  

pts1 = np.float32([[50,50],[200,50],[50,200]])  
pts2 = np.float32([[10,100],[200,50],[100,250]])  

M = cv2.getAffineTransform(pts1,pts2)  

dst = cv2.warpAffine(img,M,(cols,rows))  

plt.subplot(121),plt.imshow(img),plt.title('Input')  
plt.subplot(122),plt.imshow(dst),plt.title('Output')  
plt.show()  

图中绿点就是我们选取的三个点
在透视变换中,我们需要构造一个 3*3 的转移矩阵。为了构造这个矩阵,我们需要输入 4 个点的变换前后的坐标,并且要求其中的任意三个点不能共线。把这八个坐标先后输入 cv2.getPerpectiveTransform() 中,就能得到转移矩阵了。

img = cv2.imread('sudokusmall.png')  
rows,cols,ch = img.shape  

pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])  
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])  

M = cv2.getPerspectiveTransform(pts1,pts2)  

dst = cv2.warpPerspective(img,M,(300,300))  

plt.subplot(121),plt.imshow(img),plt.title('Input')  
plt.subplot(122),plt.imshow(dst),plt.title('Output')  
plt.show()  

OpenCV提供了两个转换函数,cv2.warpAffine和cv2.warpPerspective,通过他们你可以进行各种转换,cv2.warpAffine接受2x3的转换矩阵二cv2.warpPerspective接受3x3的转换矩阵做为输入。

属性:指定图像用哪种方式读取文件

缩放

OpenCV有一个函数cv2.resize()来干这个,图片的大小可以人工指定,或者你可以指定缩放因子。有不同的差值方式可以使用,推荐的插值方法是缩小时用cv2.INTER_AREA,放大用cv2.INTER_CUBIC(慢)和cv2.INTER_LINEAR。默认情况下差值使用cv2.INTER_www.2527.com,LINEAR。你可以使用下面两种方法来改变图片大小:

import cv2
import numpy as np

img = cv2.imread('messi5.jpg')
res = cv2.resize(img, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC)

#OR

height, width = img.shape[:2]
res = cv2.resize(img, (2*width, 2*height), interpolation=cv2.INTER_CUBIC)

cv2.IMREAD_COLOR:读入彩色图像,默认参数,Opencv 读取彩色图像为BGR模式 !!!注意

平移

平移是改变物体的位置。如果你知道在(x, y)方向的变化是(tx, ty),你可以创建转换矩阵M:

www.2527.com 1

你可以把它变成Numpy的数组,类型是np.float32的,然后把它传给cv2.warpAffine()函数,下面的例子平移(100, 50):

import cv2
import numpy as np

img = cv2.imread('messi5.jpg', 0)
rows, cols = img.shape

M = np.float32([[1,0,100],[0,1,50]])
dst = cv2.warpAffine(img, M, (cols,rows))

cv2.imshow('img', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

警告:
cv2.warpAffine()函数的第三个参数是输出图片的大小,应该是(width, height)的形式,记住width=列数,height=行数

cv2.IMREAD_GRAYSCALE:读入灰度图像。

旋转

对一个图片旋转一个θ角是通过下面这个形式的转换矩阵实现的:

www.2527.com 2

但是OpenCV提供了可选中心的缩放旋转,所以你可以按任意点旋转。转换矩阵变为:

www.2527.com 3

其中:

www.2527.com 4

要找到这个转换矩阵,OpenCV提供了一个函数,cv2.getRotationMatrix2D。看下面的例子,把图片旋转了90度

img = cv2.imread('messi5.jpg', 0)
rows, cols = img.shape

M = cv2.getRotationMatrix2D((cols/2,rows/2), 90, 1)
dst = cv2.warpAffine(img, M, (cols, rows))

结果:

www.2527.com 5

仿射变换

在仿射变换里,所有原始图片里的平行线在输出的图片里仍然平行,要找到转换矩阵,我们需要输入图片的三个点,和他们在输出图片里的对应位置,然后cv2.getAffineTransform会创建一个2x3的矩阵,然后把这个矩阵传给cv2.warpAffine.

看下面的例子,注意我选的三个点(绿色的点)

img = cv2.imread('drawing.png')
rows, cols, ch = img.shape

pts1 = np.float32([[50,50],[200,50],[50,200]])
pts2 = np.float32([[10,100],[200,50],[100,250]])

M = cv2.getAffineTransform(pts1, pts2)

dst = cv2.warpAffine(img,M,(cols, rows))

plt.subplot(121), plt.imshow(img), plt.title('Input')
plt.subplot(122), plt.imshow(dst), plt.title('Output')
plt.show()

结果:

cv2.imshow(窗口名,图像文件) 显示图像

www.2527.com 6

可以创建多个窗口

透视变换

对于透视变换,你需要一个3x3的转换矩阵。转换后直线仍然保持直线。要得到这个转换矩阵,你需要输入图片上的4个点,以及输出图片上对应的点。在这四个点中,3个不能同线。然后cv2.getPerspectiveTransform函数就能得到转换矩阵了,再用cv2.warpPerspective来接收这个3x3的转换矩阵。

代码:

img = cv2.imread('sudokusmall.png')
rows, cols, ch = img.shape

pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])

M = cv2.getPerspectiveTransform(pts1,pts2)

dst = cv2.warpPerspective(img, M,(300,300))

plt.subplot(121), plt.imshow(img), plt.title('Input')
plt.subplot(122), plt.imshow(dst), plt.title('Output')
plt.show()

www.2527.com 7

END

cv2.waitKey() 键盘绑定函数

函数等待特定的几毫秒,看是否由键盘输入。

cv2.namedWindow(窗口名,属性) 创建一个窗口

属性:指定窗口大小模式

cv2.WINDOW_AUTOSIZE:根据图像大小自动创建大小

cv2.WINDOW_NORMAL:窗口大小可调整

cv2.destoryAllWindows(窗口名) 删除任何建立的窗口

代码实例:

import cv2
 img=cv2.imread('test.py',cv2.IMREAD_COLOR)
 cv2.namedWindow('image',cv2.WINDOW_NORMAL)
 cv2.imshow('image',img)
 cv2.waitKey(0)
 cv2.destoryAllWindows()

cv2.imwrite(保存图像名,需保存图像) 保存图像

代码实例:

 import cv2
 img=cv2.imread('test.png',0)
 cv2.imshow('image',img)
 k=cv2.waitKey(0)
 if k==27: #等待 ESC 键
  cv2.destoryAllWindows()
 elif k==ord('s') #等待 's' 键来保存和退出
  cv2.imwrite('messigray.png',img)
  cv2.destoryAllWindows()

对于图像的一些操作

0x01. 获取图片属性

import cv2
img=img.imread('test.png')
print img.shape
#(768,1024,3)
print img.size
#2359296 768*1024*3
print img.dtype
#uint8

0x02. 输出文本

在处理图片时,将一些信息直接以文字的形式输出在图片上

cv2.putText(图片名,文字,坐标,文字颜色)

0x03. 缩放图片

实现缩放图片并保存,在使用OpenCV时常用的操作。cv2.resize()支持多种插值算法,默认使用cv2.INTER_LINEAR,缩小最适合使用:cv2.INTER_AREA,放大最适合使用:cv2.INTER_CUBIC或cv2.INTER_LINEAR。

res=cv2.resize(image,(2*width,2*height),interpolation=cv2.INTER_CUBIC) 

或者:

res=cv2.resize(image,None,fx=2,fy=2,interpolation=cv2.INTER_CUBIC) 

此处None本应该是输出图像的尺寸,因为后边设置了缩放因子

0x04. 图像平移

cv2.warpAffine(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]]) 

平移就是将图像换个位置,如果要沿(x,y)方向移动,移动距离为(tx,ty),则需要构建偏移矩阵M。

www.2527.com 8

例如 平移图片(100,50)

 import cv2
 img=cv2.imread('test.png',1)
 rows,cols,channel=img.shape
 M=np.float32([[1,0,100],[0,1,50]])
 dst=cv2.warpAffine(img,M,(cols,rows))
 cv2.imshow('img',dst)
 cv2.waitKey(0)
 cv2.destoryALLWindows()

其中 (cols,rows)代表输出图像的大小,M为变换矩阵,100代表x的偏移量,50代表y的偏移量,单位为像素。

0x05. 图像旋转

OpenCV中首先需要构造一个旋转矩阵,通过cv2.getRotationMatrix2D获得。

import cv2
img=cv2.imread('test.png',0)
rows,cols=img.shape
#第一个参数为旋转中心,第二个为旋转角度,第三个为旋转后的缩放因子
M=cv2.getRotationMatrix2D((cols/2,rows/2),45,0.6)
#第三个参数为图像的尺寸中心
dst=cv2.warpAffine(img,M,(2*cols,2*rows))
cv2.imshow('img',dst)
cv2.waitKey(0)
cv2.destoryALLWindows()

0x06. 仿射变换

在仿射变换中,原图中所有的平行线在结果图像中同样平行。为了创建偏移矩阵,需要在原图像中找到三个点以及它们在输出图像中的位置。然后OpenCV中提供了cv2.getAffineTransform创建2*3的矩阵,最后将矩阵传给函数cv2.warpAffine。

import cv2
import matplotlib.pyplot as plt
import numpy as np
img=cv2.imread('test.png')
rows,cols,ch=img.shape
pts1=np.float32([[50,50],[200,50],[50,200]])
pts2=np.float32([[10,100],[200,50],[100,250]])
M=cv2.getAffineTransform(pts1,pts2)
dst=cv2.warpAffine(img,M,(cols,rows))
plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()

www.2527.com 9

0x07. 透视变换

视角变换,需要一个3*3变换矩阵。在变换前后要保证直线还是直线。构建此矩阵需要在输入图像中找寻4个点,以及在输出图像中对应的位置。这四个点中的任意三个点不能共线。变换矩阵OpenCV提供cv2.getPerspectiveTransform()构建。然后将矩阵传入函数cv2.warpPerspective。

import cv2
import numpy as np
import matplotlib.pyplot as plt
img=cv2.imread('test.png')
rows,cols,ch=img.shape
pts1=np.float32([[56,65],[368,52],[28,387],[389,390]])
pts2=np.float32([[0,0],[300,0],[0,300],[300,300]])
M=cv2.getPerspectiveTransform(pts1,pts2)
dst=cv2.warpPerspective(img,M,(300,300))
plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()

www.2527.com 10

0x09. 图像 regions of Interest

有时需要对一副图像的特定区域进行操作,ROI使用Numpy索引来获得的。

import cv2
import numpy as np
import matplotlib.pyplot as plt

image=cv2.imread('test.png')
rows,cols,ch=image.shape
tall=image[0:100,300:700]
image[0:100,600:1000]=tallall
cv2.imshow("image",image)
cv2.waitKey(0)
cv2.destoryALLWindows()

www.2527.com 11

0x10. 通道的拆分/合并处理

有时需要对BGR三个通道分别进行操作。这时需要将BGR拆分成单个通道。同时有时需要把独立通道的图片合并成一个BGR图像。

使用OpenCV库函数版本

import cv2
import numpy as np
import matplotlib.pyplot as plt

image=cv2.imread('pitt1.jpg')
rows,cols,ch=image.shape
#拆分通道,cv2.split()是一个比较耗时的操作。只有需要时使用,尽量Numpy
b,g,r=cv2.split(image)
print b.shape
#(768,1024)
#合并通道
image=cv2.merge(b,g,r)

使用Numpy索引版本:

import cv2
import numpy as np
import matplotlib.pyplot as plt

image=cv2.imread('pitt1.jpg')
rows,cols,ch=image.shape
#直接获取
b=img[:,:,0]

以上这篇Python-OpenCV基本操作方法详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:

  • Python环境搭建之OpenCV的步骤方法
  • Python实现OpenCV的安装与使用示例
  • Python OpenCV获取视频的方法
  • OpenCV2.3.1 Python2.7.3 Numpy等的配置解析
  • Python 3.x 安装opencv opencv_contrib的操作方法
TAG标签:
版权声明:本文由澳门新葡8455手机版发布于www.2527.com,转载请注明出处:颜色捕捉和通道变换,OpenCV基本操作方法详解