python_Opencv_图像的基础操作

目标


 

  • 获取像素值并修改
  • 获取图像的属性(信息)
  • 图像的ROI()
  • 图像通道的拆分及合并
  • 为图像扩充边缘

几乎所有以上的操作,与Numpy 的关系都比与OpenCV 的关系更加紧密,因此熟练Numpy 可以帮助我们写出性能更好的代码。

获取像素值并修改


 

  代码:


 

 

 1 #
 2 
 3 import cv2
 4 import numpy as np
 5 
 6 # 首先打开一张图片
 7 img=cv2.imread('Koala.jpg')
 8 
 9 # 在图片中获取一个像素点
10 px=img[100,100]
11 # 打印出像素值,BGR图片显示【B,G,R】值
12 print px
13 
14 # 第三个参数0,1,2分别代表B,G,R
15 blue=img[100,100,0]
16 green=img[100,100,1]
17 red=img[100,100,2]
18 
19 print blue
20 print green
21 print red
22 
23 # 打印结果:
24 # [143 152 161]
25 # 143
26 # 152
27 # 161
28 
29 # 类似的方式可以用于修改像素值
30 img[100,100]=[255,255,255]
31 print img[100,100]
32 # 打印结果:[255 255 255]
33 
34 # 效率更快的方法,numpy中这些方法经过快速矩阵运算的优化
35 # 显示[10,10]位置的R值
36 print img.item(10,10,2)
37 # 修改它并显示
38 img.itemset((10,10,2),200)
39 print img.item(10,10,2)
40 #打印结果:
41 # 108
42 # 200
View Code

 

  注意:

    Numpy 是经过优化了的进行快速矩阵运算的软件包。所以我们不推荐逐个获取像素值并修改,这样会很慢,能有矩阵运算就不要用循环。

  对于获取每一个像素值,也许使用Numpy 的array.item() 和array.itemset() 会更好。但是返回值是标量。如果你想获得所有B,G,R 的值,

  你需要使用array.item() 分割他们。

获取图像的属性(信息)


  • 图像的属性包括:行,列,通道,图像数据类型,像素数目等。
  • img.shape 可以获取图像的形状。
  • 他的返回值是一个包含行数,列数,通道数的元组。
  • img.size返回像素点总数
  • img.dtype 返回的是图像的数据类型.

  看代码:

 1 import cv2
 2 import numpy as np
 3 
 4 # 首先打开一张图片
 5 img=cv2.imread('Koala.jpg')
 6 
 7 #图像形状
 8 print img.shape
 9 ## (384L, 512L, 3L)
10 
11 # 像素的数量
12 print img.size
13 ## 589824
14 
15 # 图像的数据类型
16 print img.dtype
17 ## uint8
View Code

 

图像ROI


 

  • 有时候我们需要对一幅图像的特定区域进行操作。
  • 例如我们要检测一副图像中眼睛的位置,我们首先应该在图像中找到脸,再在脸的区域中找眼睛,而不是直接在一幅图像中搜索。
  • 这样会提高程序的准确性和性能。ROI 也是使用Numpy 索引来获得的。

参照PDF中的一个例子,直接拿过来:

 1 import cv2
 2 import numpy as np
 3 img=cv2.imread('/home/duan/workspace/opencv/images/roi.jpg')
 4 
 5 ball=img[280:340,330:390]
 6 img[273:333,100:160]=ball
 7 
 8 cv2.imshow('image',img)
 9 cv2.waitKey(0)
10 cv2.destroyAllWindows()
View Code

结果:图中的球的部分整体复制一块到其他位置

 

图像通道的拆分及合并


 代码

 1 # -*- coding: utf-8 -*-
 2 
 3 # 有时需要对BGR 三个通道分别进行操作。
 4 # 就需要把BGR 拆分成单个通道。
 5 # 有时也需要把独立通道的图片合并成一个BGR 图像
 6 import cv2
 7 import numpy as np
 8 
 9 img=cv2.imread('Koala.jpg') # 载入图片
10 
11 cv2.imshow("img0",img)     # 未处理的图片
12 b,g,r=cv2.split(img)       # 拆分通道
13 
14 cv2.imshow("Red",r)        # R、G、B单通道图
15 cv2.imshow("Green",g)
16 cv2.imshow("Blue",b)
17 
18 img=cv2.merge([b,g,r])     # 合并图像
19 
20 cv2.imshow("img",img)      # 合并3个通道的结果
21 cv2.waitKey(0)
22 cv2.destroyAllWindows()
split 和 merge
 1 # -*- coding: utf-8 -*-
 2 
 3 # 之前的方法是用split切分,比较耗时,一般可以用numpy索引,如下
 4 import cv2
 5 import numpy as np
 6 
 7 img=cv2.imread('Koala.jpg')
 8 b=img[:,:,0]    # g=img[:,:,1] ,r=img[:,:,2]
 9 
10 cv2.imshow("blue",b)
11 
12 img[:,:,2]=0    #表示r通道置0
13 
14 cv2.imshow("r0",img)
15 
16 cv2.waitKey(0)
17 cv2.destroyAllWindows()
numpy索引操作图像通道

为图像扩充边缘


 

 1 # -*- coding: utf-8 -*-
 2 
 3 #为图像扩边(填充),有多种边框形式
 4 
 5 import cv2
 6 import numpy as np
 7 from matplotlib import pyplot as plt
 8 
 9 BLUE=[255,0,0]  # 蓝色
10 
11 img1=cv2.imread('Koala.jpg')
12 
13 # copyMakeBorder函数的参数:src源,top, bottom, left, right 对应边界的像素数目,
14 # 最后一个是borderType :边界类型
15 replicate = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REPLICATE)
16 reflect = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REFLECT)
17 reflect101 = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REFLECT_101)
18 wrap = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_WRAP)
19 constant= cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_CONSTANT,value=BLUE)
20 
21 
22 plt.subplot(231),plt.imshow(img1,'gray'),plt.title('ORIGINAL')       #231代表2行3列第一个
23 plt.subplot(232),plt.imshow(replicate,'gray'),plt.title('REPLICATE') #以此类推
24 plt.subplot(233),plt.imshow(reflect,'gray'),plt.title('REFLECT')
25 plt.subplot(234),plt.imshow(reflect101,'gray'),plt.title('REFLECT_101')
26 plt.subplot(235),plt.imshow(wrap,'gray'),plt.title('WRAP')
27 plt.subplot(236),plt.imshow(constant,'gray'),plt.title('CONSTANT')
28 
29 plt.show()
为图像加边框

 

代码中都有一些注释,这些都是我自己跟着PDF敲的一些例子程序.

 

posted @ 2016-09-07 16:30  Wenism  阅读(626)  评论(0编辑  收藏  举报