点击上方“AI搞事情”关注我们
一、像素操作
可以通过行列坐标访问像素值,对于BGR图,返回一个蓝色、绿色、红色通道的数组值,对于灰度图,仅返回相应的强度值。
代码
import cv2
img = cv2.imread('image.jpg')
px = img[32,32] # 访问(32,32)坐标像素值
print(px)
print(img[32,32,0]) # 访问B通道像素值
print(img[32,32,1]) # 访问G通道像素值
img[32,32] = [108, 108, 108] # 修改像素值
print(img[32,32])
输出
[ 93 136 145]
93
136
[108 108 108]
Note:
Numpy是一个用于快速阵列计算的优化库。因此,简单地访问每个像素值并对其进行修改将非常缓慢。
上述方法通常用于选择数组的一个区域,比如前五行和三列,对于访问单个像素点,推荐使用
array.item()
和array.itemset()
,它们返回的是一个标量。如果需要访问所有B,G,R值,需要对它们单独调用array.item()
。
代码
import cv2
img = cv2.imread('image.jpg')
p = img.item(32,32,2) # 访问R值
print(p)
img.itemset((32,32,2),100) # 修改R值
p = img.item(32,32,2)
print(p)
输出
145
100
二、图像属性
图像属性包括:行、列、通道数,数据类型,像素数目。
import cv2
img = cv2.imread('image.jpg')
print(img.shape) #图像的形状,返回值是一个包含行数(高)、列数(宽)、通道数的元组。
print(img.size) #图像的像素数目。
print(img.dtype) #图像的数据类型。
输出
(640, 1024, 3)
1966080
uint8
Note:
注意如果图像是灰度图像,
img.shape
返回的元组仅包含行数和列数,因此它是一种检查图像是灰度图像还是彩色图像的好方法。img.dtype在调试时非常重要,因为OpenCV-Python代码中的大量错误是由无效的数据类型引起的。
三、图像ROI
ROI (region of interest, 感兴趣区域)是从图像中选择的一个图像区域,这个区域是你的图像分析所关注的重点。圈定该区域以便进行进一步处理。使用ROI圈定你想处理的目标,可以减少处理时间,增加精度。比如:对于图像中的眼睛检测,在整个图像上进行第一次面部检测。当获得面部时,我们单独选择面部区域并在其内部搜索眼睛而不是搜索整个图像。
选择图像ROI并将其复制到图像中的另一个区域
代码
import cv2
img = cv2.imread('image.jpg')
husky = img[1:240,60:270]
img[61:300,270:480] = husky
cv2.imshow('show',img)
cv2.waitKey()
四、通道拆分
B,G,R三通道含有不同的颜色信息,有时需要将通道分离,在单个通道进行操作。有两种通道分离的方式:
cv2.split
函数
import cv2
img = cv2.imread('img.jpg')
b,g,r = cv2.split(img) #拆分图像通道
img = cv2.merge((b,g,r))
numpy切片
b = img[:,:,0]
单通道所有像素置零
img[:,:,2] = 0
NOTE:cv2.split()
相对比较耗时,必要时才使用。否则建议使用Numpy索引。
五、图像边框
copyMakeBorder(src, top, bottom, left, right, borderType, dst=None, value=None)
src
:输入图像top
,bottom
,left
,right
:相应方向上像素数的边框宽度value
:
cv2.BORDER_CONSTANT
cv2.BORDER_REFLECT
cv2.BORDER_REFLECT_101 or cv2.BORDER_DEFAULT
cv2.BORDER_REPLICATE
cv2.BORDER_WRAP
不同value效果代码
import cv2
from matplotlib import pyplot as plt
BLUE = [255,0,0]
img1 = cv2.imread('image.jpg')
replicate = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REPLICATE)
reflect = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REFLECT)
reflect101 = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REFLECT_101)
wrap = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_WRAP)
constant= cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_CONSTANT,value=BLUE)
plt.subplot(231),plt.imshow(img1,'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('REFLECT_101')
plt.subplot(235),plt.imshow(wrap,'gray'),plt.title('WRAP')
plt.subplot(236),plt.imshow(constant,'gray'),plt.title('CONSTANT')
plt.show()
六、应用
1. 获取图像ROI并拼接在原图下方
代码
import cv2
import numpy as np
img1 = cv2.imread('image.jpg')
img2 = img1[200: 500, 300:650, :]
w = max(img1.shape[1], img2.shape[1])
h = img1.shape[0] + img2.shape[0]
merge_img = np.zeros((h, w, 3), dtype=np.uint8)
merge_img[:img1.shape[0], :img1.shape[1]] = img1
merge_img[img1.shape[0]:, :img2.shape[1]] = img2
cv2.imwrite('res.jpg', merge_img)
cv2.imshow('img', merge_img)
cv2.imshow('img2', img1)
cv2.waitKey(0)
2. 利用通道分离去除票据红色印章
代码
import cv2
th = 180 # 二值化阈值
src = cv2.imread('image.jpg')
blue, green, red = cv2.split(src)
gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
_, binary = cv2.threshold(gray, th, 255, cv2.THRESH_BINARY)
_, red_binary = cv2.threshold(red, th, 255, cv2.THRESH_BINARY)
cv2.imshow("src", src)
cv2.imshow("gray", gray)
cv2.imshow("binary", binary)
cv2.imshow("red channel", red)
cv2.imshow("blue channel", blue)
cv2.imshow("green channel", green)
cv2.imshow("red+binary", red_binary)
new_img = cv2.merge((blue, green, red_binary))
cv2.imshow("new image", new_img)
cv2.waitKey(0)
“参考:如何去除票据上的印章: https://www.cnblogs.com/skyfsm/p/7638301.html
往期推荐
长按二维码关注我们
有趣的灵魂在等你