可以根据像素的行和列的坐标获取它的像素值。对 BGR 图像而言,返回值为 B,G,R 的值。
import cv2
image_name = "img/003.jpg"
img = cv2.imread(image_name)
cv2.imshow("origin", img)
high, wide, channel = img.shape
print "high is {0}, wide is {1}, channel is {2}".format(high, wide, channel)
# high is 198, wide is 198, channel is 3
for row in range(high):
for col in range(wide):
b, g, r = img[row, col]
b = 255 - b
g = 255 - g
r = 255 - r
img[row, col] = b, g, r # 修改像素值
cv2.imshow("output", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
显示结果:
如果上面的难以理解,可以看下面的这些操作,希望能帮助读者更好的理解。
>>> a = np.array([[[1, 2], [3,4], [5, 6]], [[11, 22], [33,44], [55, 66]]])
>>> a.shape
(2, 3, 2)
>>> a
array([[[ 1, 2],
[ 3, 4],
[ 5, 6]],
[[11, 22],
[33, 44],
[55, 66]]])
>>> a.ndim
3
>>> a.size
12
>>> a[0, 1]
array([3, 4])
>>> a[1, 2]
array([55, 66])
>>> h, w = a[1, 2]
>>> h,w
(55, 66)
图像像素也可以进行加、减、乘、除操作,但是必须要注意,进行算术运算操作的时,必须要保证两幅图像的大小、数据类型和通道数目必须相同。
使用示例如下:
import cv2
import numpy as np
img1 = cv2.imread("img/003.jpg")
img2 = cv2.imread("img/003_gray.jpg")
cv2.imshow("img1", img1)
cv2.imshow("img2", img2)
h, w, ch = img1.shape
add_result = np.zeros(img1.shape, img1.dtype)
cv2.add(img1, img2, add_result)
cv2.imshow("add_result", add_result)
sub_result = np.zeros(img1.shape, img1.dtype)
cv2.subtract(img1, img2, sub_result)
cv2.imshow("sub_result", sub_result)
mul_result = np.zeros(img1.shape, img1.dtype)
cv2.multiply(img1, img2, mul_result)
cv2.imshow("mul_result", mul_result)
div_result = np.zeros(img1.shape, img1.dtype)
cv2.divide(img1, img2, div_result)
cv2.imshow("div_result", div_result)
cv2.waitKey(0)
cv2.destroyAllWindows()
这里包括的按位操作有:AND,OR,NOT,XOR 等。当我们提取图像的一部分,选择非矩形 ROI 时这些操作会很有用。下面的例子就是教给我们如何改变一幅图的特定区域。
import cv2
import numpy as np
# create img one
img1 = np.zeros(shape=(200, 200, 3), dtype=np.uint8)
img1[50:100, 50:100, 1] = 255
img1[50:100, 50:100, 2] = 255
cv2.imshow("img1", img1)
# create img two
img2 = np.zeros(shape=(200, 200, 3), dtype=np.uint8)
img2[75:150, 75:150, 2] = 255
cv2.imshow("img2", img2)
dst1 = cv2.bitwise_and(img1, img2)
dst2 = cv2.bitwise_or(img1, img2)
dst3 = cv2.bitwise_xor(img1, img2)
cv2.imshow("dst1", dst1)
cv2.imshow("dst2", dst2)
cv2.imshow("dst3", dst3)
img4 = cv2.imread("img/003.jpg")
dst4 = cv2.bitwise_not(img4)
cv2.imshow("dst4", dst4)
cv2.waitKey(0)
cv2.destroyAllWindows()
像素值统计涉及到的知识点有以下几个
OpenCV 相关的 API 知识点
注意:像素值统计必须是单通道的图片,所以 cv2.imread 时必须加上图片的载入类型。
源码中有如下提示:
'''
The function do not work with multi-channel arrays. If you need to find minimum or maximum
elements across all the channels, use Mat::reshape first to reinterpret the array as
single-channel.
'''
import cv2
import numpy as np
img = cv2.imread("img/003.jpg", cv2.IMREAD_GRAYSCALE)
minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(img)
print minVal, maxVal, minLoc, maxLoc # 0.0 255.0 (128, 24) (120, 12)
means, stddev = cv2.meanStdDev(img)
print means, stddev # [[97.23278237]] [[45.80720813]]
img[np.where(img < means)] = 0
img[np.where(img > means)] = 255
cv2.imshow("binary", img)
cv2.waitKey(0)
cv2.destroyAllWindows()