欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

OpenCV-python学习笔记之图像操作

程序员文章站 2022-03-25 17:00:26
...

为了快速学习,按照中文教程中的顺序,走一遍python接口。英文能力较强者,可以从对应的英文教程自己翻译学习。

一、OpenCV图像的基本操作

  1. 获取并修改像素值

读取一副图像,根据像素的行和列的坐标获取它的像素值,对于RGB图像而言,返回RGB的值,对于灰度图则返回灰度值。

import cv2
import numpy
img = cv2.imread('0.jpg')
px = img[100, 100]
print ("img(100, 100)的像素值:", px)  #返回的值分别代表:蓝色、绿色、红色
#返回单一颜色值,如0、1、2分别对应该点蓝色、绿色、红色的值
blue = img[100, 100, 0]
print ("img(100, 100)的蓝色对应的像素值:", blue)
green = img[100, 100, 1]
print ("img(100, 100)的绿色对应的像素值:", green)
rad = img[100, 100, 2]
print ("img(100, 100)的红色对应的像素值:", rad)

img[101,101]=[255,255,255]
print(img[101,101])

注意:若读取图片的位置不正确,读取不报错,但是在下面会报错。
numpy是经过优化了的进行快速矩阵运算的包,所以不推荐逐个获取像素值并修改,能矩阵运算就不要用循环。
例如前5行的后3列,用numpy的array.item()和array.itemset()会更好。但是返回是标量,如果想获得所有RGB的值,需要使用array.item()分割他们。

#coding:utf8
import cv2
import numpy as np
 
img = cv2.imread('F:/picture.jpg')
#返回单一颜色值,如蓝色、绿色、红色
blue = img.item(100, 100, 0)
print ("blue:", blue)
green = img.item(100, 100, 1)
print ("green:", green)
red = img.item(100, 100, 2)
print ("red:", red)
#修改图像的像素值
px = img.itemset((100, 100, 2), 100)
print ("修改之后的像素值:", px)
  1. 获取图像属性

图像属性包括:行,列,通道,图像数据类型,像素数目等。

  • img.shape 可以获得图像的形状,返回值是一个包含行数,列数,通道数的元组。
  • img.size 可以返回图像的像素数目。
  • img.dtype 返回图像的数据类型,在debug时很重要,因为OpenCV-Python代码中经常出现数据类型的不一致。
#coding:utf8
import cv2
import numpy as np
 
img = cv2.imread('0.jpg')
print ("访问图像属性", img.shape)
print ("像素的总数", img.size)
print ("图像色数据类型", img.dtype)
#输出结果
访问图像属性 (3000, 4000, 3)
像素的总数 36000000
图像色数据类型 uint8
  1. 图像ROI

对图像的特定区域操作。ROI是使用numpy索引来获得的。

import cv2
import numpy as np

img = cv2.imread('0.jpg')
ball = img[280:340, 330:390]    #获取该区域
img[273:333, 100:160] = ball	# 将另一区域变为该区域
  1. 拆分及合并图像通道

有时需要对RGB三个通道分别操作,这就需要拆分RGB为单个通道。有时需要把独立的通道的图片合成一个RGB。

r,g,b=cv2.split(img)#拆分
img=cv2.merge(r,g,b)#合并

或者

b=img[:,:,0]#拆分b通道

假如想使所有红色通道值都为0,不必拆分再赋值,可以使用numpy索引,这样更快

img[:,:,2]=0

cv2.split()是比较耗时的操作,能用numpy就尽量使用。

  1. 为图像扩边(填充)

想为图像周围建一个边可以使用cv2.copyMakeBorder()函数。这经常在卷积运算或0填充时被用到。
具体参数如下:

  • src:输入图像;
  • top, bottom, left, right: 在相应方向上的像素数量中的边界宽度;
  • borderType -标志定义要添加的边界类型;
    1、 cv2.BORDER_CONSTANT添加有颜色的常数值边界,还需要下一个参数(value)
    2 、cv2.BORDER_REFLIECT边界元素的镜像。例如:fedcba | abcdefgh | hgfedcb
    3、 cv2.BORDER_101或者cv2.BORDER_DEFAULT跟上面一样,但稍作改动,例如:gfedcb | abcdefgh | gfedcba
    4 、cv2.BORDER_REPLICATE复后一个元素。例如: aaaaaa| abcdefgh|hhhhhhh
    5 、cv2.BORDER_WRAP 不知怎么了, 就像样: cdefgh| abcdefgh|abcdefg
  • value边界颜色
import cv2
import numpy
from matplotlib import pyplot as plt
img = cv2.imread('roi.jpg')
blue = [255,0,0]
replicate = cv2.copyMakeBorder(img,200,200,200,200,cv2.BORDER_REPLICATE)
reflect = cv2.copyMakeBorder(img,200,200,200,200,cv2.BORDER_REFLECT)
reflect101 = cv2.copyMakeBorder(img,200,200,200,200,cv2.BORDER_REFLECT101)
wrap = cv2.copyMakeBorder(img,200,200,200,200,cv2.BORDER_WRAP)
constant = cv2.copyMakeBorder(img,200,200,200,200,cv2.BORDER_CONSTANT,value=blue)

plt.subplot(231),plt.imshow(img,'gray'),plt.title('original')
plt.subplot(232),plt.imshow(replicate,'gray'),plt.title('replicate')
plt.subplot(233),plt.imshow(reflect,'gray'),plt.title('reflect')
plt.subplot(234),plt.imshow(reflect101,'gray'),plt.title('reflect101')
plt.subplot(235),plt.imshow(wrap,'gray'),plt.title('wrap')
plt.subplot(236),plt.imshow(constant,'gray'),plt.title('constant')

plt.show()

在图片像素较大时,可以调大四周的值,现象更加明显,其效果入下:
OpenCV-python学习笔记之图像操作