这两种技术应该会产生相似的结果。为什么是图像
在 for 循环技术中被倒置?
因为你应该这样做,转换数据类型:
imgc = np.uint64(img_paris.copy()) # <-- convert datatype
for x in range(yellow_image.shape[0]):
for y in range(yellow_image.shape[1]):
imgc[x,y] = (imgc[x,y] * yellow_image[x,y])
说明第 1 部分(dtype)
这是因为dtype 在重新分配整个矩阵时会发生变化,而重新分配切片时不会发生:
a = np.array([[1]], np.uint8)
b = np.array([[1]], np.float64)
a[0] = a[0] * b[0] # assigning slices dtype of a does not change
print(a.dtype) #=> uint8
a = a * b # while assigning the full matrix it does
print(a.dtype) #=> float64
如果您在看到这个的过程中打印您的dtype:
yellow_image_1 = np.ones(img_paris.shape) * 255
print(yellow_image_1.dtype) #=> float64
yellow_image_1[:,:,0] *= 0
print(yellow_image_1.dtype) #=> float64
imgc_1 = img_paris.copy()
print(imgc_1.dtype) #=> uint8
imgc_1 = (imgc_1 * yellow_image_1)
print(imgc_1.dtype) #=> float64
还有这个:
yellow_image_2 = np.ones(img_paris.shape) * 255
print(yellow_image_2.dtype) #=> float64
yellow_image_2[:,:,0] *= 0
print(yellow_image_2.dtype) #=> float64
imgc_2 = img_paris.copy()
print(imgc_2.dtype) #=> uint8
for x in range(yellow_image_2.shape[0]):
for y in range(yellow_image_2.shape[1]):
imgc_2[x,y] = (imgc_2[x,y] * yellow_image_2[x,y])
print(imgc_2.dtype) #=> uint8
所以你最终会得到不同的dtype 矩阵。
解释第 2 部分(OpenCV BGR)
如前所述,请记住,OpenCv 使用BGR format,每个像素值从0 变为255,np.uint8 表示。
因此,如果您使用例如 matplotlib,为了显示图像,您必须交换 B 和 R 通道:
img_paris = cv2.imread('3ClnT.jpg')
plt.imshow(img_paris[:,:,::-1])
如果您使用cv2.imwrite() 或cv2imshow() 进行保存,则不需要这样做,例如:
cv2.imwrite('paris.jpg', img_paris)
也就是说,您可以使用这个单行命令生成纯黄色图像:
yellow_image = np.ones_like(img_paris) * (0, 255, 255)
并显示或保存:
plt.imshow(yellow_image[:,:,::-1])
cv2.imwrite('solid_yellow.jpg', yellow_image)
现在,乘法 paris_yellow = img_paris * yellow_image 的结果大于 255:
使用 RGB 数据将输入数据剪切到 imshow 的有效范围([0..1] 用于浮点数或 [0..255] 用于整数)。
因此,当您相乘时,您最终会得到一个最大像素值,它可以是 255 * 255 = 65025。
然后你需要:
- 将乘法项转换为支持高达
65025 的整数的数据类型
- 乘法后,归一化然后转换回
uint8
这是一个例子:
paris_yellow_2 = np.int64(img_paris) * np.int64(yellow_image) # <- use int64 terms
max_px_val = np.amax(paris_yellow_2) # <-- Max pixel alue
paris_yellow_2 = np.uint8((paris_yellow_2/max_px_val) * 255) # <- normalize and convert back to uint8
plt.imshow(paris_yellow_2[:,:,::-1])
结果如下:
其他选项,给出不同的结果是将G 和R 通道相乘以获得大于1 的系数,然后裁剪值>255。在这种情况下,您需要使用浮点数dtype:
paris_yellow_3 = np.float64(img_paris) * (1, 3, 3)
paris_yellow_3[paris_yellow_3 > 255] = 255 # <- crops to 255 pixels values > 255
paris_yellow_3 = paris_yellow_3.astype(np.uint8) # <- back to uint8
在这种情况下,B 乘以 1(没有变化),G 和 R 乘以 3,得到以下结果: