从 Python 中的图像中减去 RGB 值
Posted
技术标签:
【中文标题】从 Python 中的图像中减去 RGB 值【英文标题】:subtracting RGB values from an Image in Python 【发布时间】:2017-12-12 22:59:34 【问题描述】:我正在一个项目中工作,我需要从图像中减去 RGB 值。例如,我想从 RED 中减去 BLUE 通道,因此 RED 得到减法的差值。
我有图像的下一个属性: 尺寸:1456x2592, bpp:3
我使用的图像给了我以下数组:
[[[ 63 58 60]
[ 63 58 60]
[ 64 59 61]
...,
[155 155 161]
[155 155 161]
[155 155 161]]
[[ 58 53 55]
[ 60 55 57]
[ 62 57 59]
...,
[157 157 163]
[157 157 163]
[158 158 164]]
我知道这些是图像中的值(RGB),所以现在我继续编写代码(我基于this code)
import cv2
import numpy as np
from PIL import Image
# read image into matrix.
m = cv2.imread("ITESO.jpeg")
# get image properties.
h,w,bpp = np.shape(m)
# iterate over the entire image.
# BLUE = 0, GREEN = 1, RED = 2.
for py in range(0,h):
for px in range(0,w):
#m[py][px][2] = 2
n = m[py][px][2] //n takes the value of RED
Y = [n, 0, 0] //I create an array with [RED, 0, 0]
m, Y = np.array(m), np.array(Y)
m = np.absolute(m - Y) //Get the matriz with the substraction
y = 1
x = 1
print (m)
print (m[x][y])
#display image
#cv2.imshow('matrix', m)
#cv2.waitKey(0)
cv2.imwrite('new.jpeg',m)
img = Image.open('new.jpeg')
img.show()
img = Image.open('new.jpeg').convert('L')
img.save('new_gray_scale.jpg')
img.show()
当我打印 J 矩阵时,它会给出以下数组:
B,G,R
蓝色 = 蓝色 - 红色
[[[ 3 58 60]
[ 3 58 60]
[ 4 59 61]
...,
[ 95 155 161]
[ 95 155 161]
[ 95 155 161]]
[[ 2 53 55]
[ 0 55 57]
[ 2 57 59]
...,
[ 97 157 163]
[ 97 157 163]
[ 98 158 164]]
但我无法打开新图像,如果我将一个 RGB 通道设置为一个值,它会显示图像。我为此使用下一行:
import cv2
import numpy as np
# read image into matrix.
m = cv2.imread("python.png")
# get image properties.
h,w,bpp = np.shape(m)
# iterate over the entire image.
for py in range(0,h):
for px in range(0,w):
m[py][px][0] = 0 //setting channel Blue to values of 0
# display image
cv2.imshow('matrix', m)
cv2.waitKey(0)
如何将 RGB 通道相减?
PS:在 MatLab 中它就像一个魅力,但我无法在 python 中做到这一点。
【问题讨论】:
您总是可以使用 split 函数分离通道,然后进行减法,然后再次合并它们。 Here 是如何拆分或合并它们。然后只要你喜欢就减去另一个,比如diff = b-r
,然后你可以使用你喜欢的合并
感谢您回复我,我发现图像实际上是保存在文件夹中(我觉得很愚蠢),但 img.show 由于某种原因不起作用。谢谢老兄。
【参考方案1】:
将 RGB 负值操作为零的代码...
m = cv2.imread("img.jpg")
# get image properties.
h,w,bpp = np.shape(m)
# iterate over the entire image.
# BLUE = 0, GREEN = 1, RED = 2.
for py in range(0,h):
for px in range(0,w):
n = m[py][px][1]
Y = [0, 0, n]
m, Y = np.array(m), np.array(Y)
a = (m - Y)
if (a[py][px][0] <=0): #if Blue is negative or equal 0
a[py][px][0] = 0 #Blue set to 0
cv2.imwrite('img_R-G.jpg',a)
img = Image.open('img_R-G.jpg').convert('L')
img.save('img_R-G_GS.jpg')
【讨论】:
【参考方案2】:注意这个操作是将矩阵(图像)的dtype
从uint8
更改为int32
,这可能会导致其他problems。 IMO,这样做的更好(和更有效)的方法是:
import cv2
import numpy as np
img = cv2.imread('image.png').astype(np.float) # BGR, float
img[:, :, 2] = np.absolute(img[:, :, 2] - img[:, :, 0]) # R = |R - B|
img = img.astype(np.uint8) # convert back to uint8
cv2.imwrite('new-image.png', img) # save the image
cv2.imshow('img', img)
cv2.waitKey()
【讨论】:
效果很好,我将“np.absolute”切换为“np.array”,所以我可以看到负值,然后将其转换为零值。例如R(40), B(60) R = R - B = -20。在我之前的代码中,我使用“if”条件将这些负值转换为零,每个像素的像素。但是我找不到使用此代码的方法。你知道一个简单的方法吗?....我会回答我自己的问题来发布那段代码,谢谢:) @AndresMitre 是的,使用img[:, :, 2] = np.clip(img[:, :, 2] - img[:, :, 0], 0.0, 255.0)
。以上是关于从 Python 中的图像中减去 RGB 值的主要内容,如果未能解决你的问题,请参考以下文章