所有的操作与 NumPy
相关。熟悉 NumPy
会写出更好的代码。
import numpy as np
import cv2
img = cv2.imread('messi5.jpg')
# 获取 y = 80, x = 180 位置处的像素值
px = img[80, 180]
print(px) # 77, 84, 180
# 设置 y = 80, x = 180 位置处的像素为白色
img[80, 180] = [255, 255, 255]
# 获取 y = 80, x = 200 位置处蓝色通道的值,通道顺序为 B(blue), G(green), R(red)
bluepx = img[80, 200, 0]
print(bluepx) # 96
cv2.imshow("image", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
NumPy 是一个快速数组运算的优化库,简单的像素访问和修改可能会比较慢,所以是不推荐的。取几行或者取几列会很快,但是对于单个像素的访问,NumPy有 array.item()和array.itemset()会更好,它们总是会返回一个标量,但是如果想要访问所有的BGR的值,需要分别使用 array.item() 获得每个值。
# Better pixel accessing and editing method :
# 修改 y = 80, x = 160 位置处红色通道像素值为255
img.itemset((80, 160, 2), 255)
# 访问 y = 80, x = 160 位置处的各像素值
b = img.item(80, 160, 0)
g = img.item(80, 160, 1)
r = img.item(80, 160, 2)
cv2.imshow("image", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
import numpy as np
import cv2
img = cv2.imread('messi5.jpg')
print( img.shape )
print( img.size )
print( img.dtype )
(342, 548, 3)
562248
uint8
import numpy as np
import cv2
img = cv2.imread('messi5.jpg')
# 通过 NumPy 的方式取得球位置的图像
# 并将取出来的ROI图像复制到图像其他位置
# cropped = img[start_row:end_row, start_col:end_col]
ball = img[280:340, 330:390]
img[273:333, 100:160] = ball
cv2.imshow("image", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
import numpy as np
import cv2
img = cv2.imread('messi5.jpg')
# 将图像的通道分离为 BGR 通道
b,g,r = cv2.split(img)
# 合并通道
img = cv2.merge((b,g,r))
# numpy的索引方式更快
img[:,:,2] = 0
cv2.imshow("image", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
NOTE: cv2.split
是一个耗时的函数,只有在必须使用的时候才去用它,否则用 NumPy
的通道索引更好一些。
接口
void cv::copyMakeBorder ( InputArray src,
OutputArray dst,
int top,
int bottom,
int left,
int right,
int borderType,
const Scalar & value = Scalar()
);
cv2.copyMakeBorder( src, top, bottom, left, right, borderType[, dst[, value]] ) -> dst
参数
扩边类型
扩边类型 | 描述 |
---|---|
BORDER_CONSTANT Python: cv2.BORDER_CONSTANT | 常数iiiiii|abcdefgh|iiiiiii with some specified i |
BORDER_REPLICATE Python: cv2.BORDER_REPLICATE | 邻近复制 aaaaaa|abcdefgh|hhhhhhh |
BORDER_REFLECT Python: cv2.BORDER_REFLECT | 镜像 fedcba|abcdefgh|hgfedcb |
BORDER_WRAP Python: cv2.BORDER_WRAP | 打包 cdefgh|abcdefgh|abcdefg |
BORDER_REFLECT_101 Python: cv2.BORDER_REFLECT_101 | 差一个镜像 gfedcb|abcdefgh|gfedcba |
BORDER_TRANSPARENT Python: cv2.BORDER_TRANSPARENT | 类似于插值 uvwxyz|abcdefgh|ijklmno |
BORDER_REFLECT101 Python: cv2.BORDER_REFLECT101 | same as BORDER_REFLECT_101 |
BORDER_DEFAULT Python: cv2.BORDER_DEFAULT | same as BORDER_REFLECT_101 |
BORDER_ISOLATED Python: cv2.BORDER_ISOLATED | 不超出范围 |
import cv2
import numpy as np
from matplotlib import pyplot as plt
BLUE = [255, 0, 0]
resizeratio = 0.4
img0 = cv2.imread('opencv-logo.png')
img0h, img0w, _ = img0.shape
img1h, img1w = int(img0h * resizeratio), int(img0w * resizeratio)
img1 = cv2.resize(img0, (img1w, img1h))
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)
# 显示的不是很明显,还是用 OpenCV 的 imshow 显示
# 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()
cv2.namedWindow("ORIGINAL")
cv2.namedWindow("REPLICATE")
cv2.namedWindow("REFLECT")
cv2.namedWindow("REFLECT_101")
cv2.namedWindow("WRAP")
cv2.namedWindow("CONSTANT")
cv2.moveWindow("ORIGINAL", 100, 100)
cv2.moveWindow("REPLICATE", 130 + img1w , 100)
cv2.moveWindow("REFLECT", 160 + img1w * 2, 100)
cv2.moveWindow("REFLECT_101", 100, 130 + img1h)
cv2.moveWindow("WRAP", 130 + img1w , 130 + img1h)
cv2.moveWindow("CONSTANT", 160 + img1w * 2, 130 + img1h)
cv2.imshow("ORIGINAL", img1)
cv2.imshow("REPLICATE", replicate)
cv2.imshow("REFLECT",reflect)
cv2.imshow("REFLECT_101",reflect101)
cv2.imshow("WRAP",wrap)
cv2.imshow("CONSTANT",constant)
cv2.waitKey(0)
cv2.destroyAllWindows()
NOTE:
matplotlib
显示是按照RGB
显示的,而OpenCV
显示的顺序是BGR
,所以看起来颜色怪怪的。
方法1:
pltImg = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
方法2:
b, g, r = cv2.split(image)
pltImg = cv2.merge([r, g, b])
方法3:
pltImg = image[:, :, :: -1]
在 subplot 之前插入以下代码,并用matplotlib
显示:
b, g, r = cv2.split(wrap)
wrap = cv2.merge([r, g, b])
constant = constant[:, :, :: -1]