本文已参与「新人创作礼」活动,一起开启掘金创作之路。
在数字图像处理领域,免不了与图像打交道,因此对于图像的内部细节,我们需要清楚一些,这样方便后期的算法设计。从最基础的概念来讲,0-255可以构成一个字节表示,目前的图像中每一个像素通道都由一个字节单独描述。
在Opencv中,.array类型中二维或者三维数组组成图像,8位的灰度图像是一个含有字节值的二维数组,对于彩色图像,是一个24位的三维数组,同样也包含了字节值。在访问这些图像的像素时,我们可以用相关的表达式来访问,例如img[0,0]、img[0,0,0]等,分表代表像素的y坐标、x坐标和颜色通道。
一幅每个通道均有8位的图像,可以利用Opencv的函数将其显示转换位标准的Python bytearray格式:
byte_img = bytearray(image)
如果bytearray含有恰当顺序的字节,可以通过显示转换和重构,得到numpy.array形式的图像:
gray_img = numpy.array(grayNytearray).reshape(hight, width)
bgr_img = numpy.array(bgrBytearray).reshape(hight, width)
import cv2
import numpy as np
image = cv2.imread("./2.jpg")
byte_img = bytearray(image)
bgr_img = np.array(byte_img).reshape(image.shape[0], image.shape[1], 3)
cv2.imshow("byteimage", image)
cv2.imshow("bgrimage", bgr_img)
cv2.waitKey(0)
上面使用的是自然图像进行举例,下面我们自己构造一些随机数生成一副图像验证上面的代码。
import cv2
import numpy as np
import os
randomByteArray = bytearray(os.urandom(300000))
flatNumpyArray = np.array(randomByteArray)
gray_img = flatNumpyArray.reshape(500, 600)
cv2.imshow("randoGrayImage", gray_img)
BGR_img = flatNumpyArray.reshape(200, 500, 3)
cv2.imshow("randoBGRImage", BGR_img)
cv2.waitKey(0)
结果如下所示
上面是灰度图,下面是彩色图。
使用np.array访问图像中的像素数据
有时候我们需要对图像进行一些操作,此时我们所操作的直接对象是像素,直接凭空叙述有些抽象,直接上代码演示更加直观一些。
image = cv2.imread("./2.jpg")
image[20, 20] = [0, 0, 0]
image[20, 21] = [0, 0, 0]
image[21, 21] = [0, 0, 0]
image[21, 20] = [0, 0, 0]
image[22, 22] = [0, 0, 0]
image[21, 22] = [0, 0, 0]
image[22, 21] = [0, 0, 0]
cv2.imshow("image", image)
cv2.waitKey(0)
效果如下
除了上述修改像素的方法之外还可以用函数修改像素点
image = cv2.imread("./2.jpg")
# 打印指定位置的像素值
# print(image.item(200, 200, 0))
# print(image[200, 200, 0])
# 函数修改像素值
print(image[20, 20, 0])
image.itemset((20, 20, 0), 0)
print(image[20, 20, 0])
对于图片的处理要非常谨慎,毕竟一张图片不算小,特别是医学图像,如果按照遍历的方式对图像进行操作,那将非常耗时,结合numpy的特性,我们可以用切片操作的思想处理图像。如下
image = cv2.imread("./2.jpg")
image[:, :, 0] = 0
cv2.imshow("image", image)
cv2.waitKey(0)
效果如下图所示
图像的区域剪裁
image = cv2.imread("./2.jpg")
roi = image[200:600, 200:600]
image = roi
cv2.imshow("image", image)
cv2.waitKey(0)