所以我试图对图像的强度进行平均。因此,我要做的是将原始图像转换为HSI,找到原始图像的平均强度,然后在将其转换回RGB之前修改HSI图像的强度。但是,我目前面临将HSI重新转换为RGB的问题
def HSI_TO_RGB(Average, img):
with np.errstate(divide='ignore', invalid='ignore'):
#Load image with 32 bit floats as variable type
bgr = np.float32(img)/255
#Separate color channels
blue = bgr[:,:,0]
green = bgr[:,:,1]
red = bgr[:,:,2]
#Calculate Saturation
def calc_saturation(red, blue, green):
minimum = np.minimum(np.minimum(red, green), blue)
saturation = 1 - (3 / (red + green + blue + 0.001) * minimum)
return saturation
#Calculate Hue
def calc_hue(red, blue, green):
hue = np.copy(red)
for i in range(0, blue.shape[0]):
for j in range(0, blue.shape[1]):
hue[i][j] = 0.5 * ((red[i][j] - green[i][j]) + (red[i][j] - blue[i][j])) / \
math.sqrt((red[i][j] - green[i][j])**2 +
((red[i][j] - blue[i][j]) * (green[i][j] - blue[i][j])))
hue[i][j] = math.acos(hue[i][j])
if blue[i][j] <= green[i][j]:
hue[i][j] = hue[i][j]
else:
hue[i][j] = ((360 * math.pi) / 180.0) - hue[i][j]
return hue
huehue = calc_hue(red, blue, green) * 255
satsat = calc_saturation(red, blue, green) * 255
for huehue in range(0,1):
backR = (Average + (2 * Average * satsat))
backG = (Average - (Average * satsat))
backB = (Average - (Average * satsat))
final = cv2.merge((backR, backG, backB))
return final
for huehue in range(1,120):
backR = (int) (Average + (Average * satsat) * cos(huehue) / cos(60-huehue))
backG = (int) (Average + (Average * satsat) * (1 - cos(huehue) / cos(60-huehue)))
backB = (int) (Average - (Average * satsat))
final = cv2.merge((backR, backG, backB))
return final
for huehue in range(120,121):
backR = (int) (Average - (Average * satsat))
backG = (int) (Average + (2 * Average * satsat))
backB = (int) (Average - (Average * satsat))
final = cv2.merge((backR, backG, backB))
return final
for huehue in range(121,240):
backR = (int) (Average - (Average * satsat))
backG = (int) (Average + (Average * satsat) * cos(huehue-120) / cos(180-huehue))
backB = (int) (Average + (Average * satsat) * (1 - cos(huehue-120) / cos(180-huehue)))
final = cv2.merge((backR, backG, backB))
return final
for huehue in range(240,241):
backR = (int) (Average - (Average * satsat))
backG = (int) (Average - (Average * satsat))
backB = (int) (Average + (2 * Average * satsat))
final = cv2.merge((backR, backG, backB))
return final
for huehue in range(241,360):
backR = (int) (Average + (Average * satsat) * (1 - cos(huehue-240) / cos(300-huehue)))
backG = (int) (Average - (Average * satsat))
backB = (int) (Average + (Average * satsat) * cos(huehue-240) / cos(300-huehue))
final = cv2.merge((backR, backG, backB))
return final
final=final/360*255
return final
我主要是从>RGB to HSI and HSI to RGB conversion谁能给我一些解决问题的建议?
存在多个问题,但我不确定我是否已解决所有问题:
for
而不是if
:for huehue in range(1,120)
应该是if 1 <= huehue_deg[i][j] < 120
。 math.cos
使用弧度作为输入。您正在使用度数:cos(60-huehue)
另一方面,calc_hue
返回以弧度表示的色相,并且您将range(1,120)
用作度数。 blue = bgr[:,:,0]
最后:final = cv2.merge((backR, backG, backB))
huehue = calc_hue(red, blue, green) * 255
和satsat = calc_saturation(red, blue, green) * 255
不在这里。 Average
参数是什么。我假定它是转换为float32
(范围[0,1])后的RGB平均值。以下(更正的)以下代码读取输入图像,将其传递到HSI_TO_RGB
并显示输出:
import cv2
import numpy as np
import math
from math import cos, radians
def HSI_TO_RGB(Average, img):
with np.errstate(divide='ignore', invalid='ignore'):
#Load image with 32 bit floats as variable type
bgr = np.float32(img)/255
#Separate color channels
blue = bgr[:,:,0]
green = bgr[:,:,1]
red = bgr[:,:,2]
#Calculate Saturation
def calc_saturation(red, blue, green):
minimum = np.minimum(np.minimum(red, green), blue)
saturation = 1 - (3 / (red + green + blue + 0.001) * minimum)
return saturation
#Calculate Hue
def calc_hue(red, blue, green):
hue = np.copy(red)
for i in range(0, blue.shape[0]):
for j in range(0, blue.shape[1]):
hue[i][j] = 0.5 * ((red[i][j] - green[i][j]) + (red[i][j] - blue[i][j])) / \
math.sqrt((red[i][j] - green[i][j])**2 +
((red[i][j] - blue[i][j]) * (green[i][j] - blue[i][j])))
hue[i][j] = math.acos(hue[i][j])
if blue[i][j] <= green[i][j]:
hue[i][j] = hue[i][j]
else:
hue[i][j] = ((360 * math.pi) / 180.0) - hue[i][j]
return hue
huehue = calc_hue(red, blue, green) # * 255
satsat = calc_saturation(red, blue, green) # * 255
huehue = np.nan_to_num(huehue) # Replace nan with zeros
# Convert from radians to degrees
huehue_deg = np.rad2deg(huehue)
# Initiazlie with zeros
backR = np.zeros_like(satsat)
backG = np.zeros_like(satsat)
backB = np.zeros_like(satsat)
for i in range(0, satsat.shape[0]):
for j in range(0, satsat.shape[1]):
if 0 <= huehue_deg[i][j] < 1:
backR[i][j] = (Average[i][j] + (2 * Average[i][j] * satsat[i][j]))
backG[i][j] = (Average[i][j] - (Average[i][j] * satsat[i][j]))
backB[i][j] = (Average[i][j] - (Average[i][j] * satsat[i][j]))
elif 1 <= huehue_deg[i][j] < 120:
backR[i][j] = (Average[i][j] + (Average[i][j] * satsat[i][j]) * cos(huehue[i][j]) / cos(radians(60)-huehue[i][j]))
backG[i][j] = (Average[i][j] + (Average[i][j] * satsat[i][j]) * (1 - cos(huehue[i][j]) / cos(radians(60)-huehue[i][j])))
backB[i][j] = (Average[i][j] - (Average[i][j] * satsat[i][j]))
elif 120 <= huehue_deg[i][j] < 121:
backR[i][j] = (Average[i][j] - (Average[i][j] * satsat[i][j]))
backG[i][j] = (Average[i][j] + (2 * Average[i][j] * satsat[i][j]))
backB[i][j] = (Average[i][j] - (Average[i][j] * satsat[i][j]))
elif 121 <= huehue_deg[i][j] < 240:
backR[i][j] = (Average[i][j] - (Average[i][j] * satsat[i][j]))
backG[i][j] = (Average[i][j] + (Average[i][j] * satsat[i][j]) * cos(huehue[i][j]-radians(120)) / cos(radians(180)-huehue[i][j]))
backB[i][j] = (Average[i][j] + (Average[i][j] * satsat[i][j]) * (1 - cos(huehue[i][j]-radians(120)) / cos(radians(180)-huehue[i][j])))
elif 240 <= huehue_deg[i][j] < 241:
backR[i][j] = (Average[i][j] - (Average[i][j] * satsat[i][j]))
backG[i][j] = (Average[i][j] - (Average[i][j] * satsat[i][j]))
backB[i][j] = (Average[i][j] + (2 * Average[i][j] * satsat[i][j]))
else: #elif 241 <= huehue_deg[i][j] < 360:
backR[i][j] = (Average[i][j] + (Average[i][j] * satsat[i][j]) * (1 - cos(huehue[i][j]-radians(240)) / cos(radians(300)-huehue[i][j])))
backG[i][j] = (Average[i][j] - (Average[i][j] * satsat[i][j]))
backB[i][j] = (Average[i][j] + (Average[i][j] * satsat[i][j]) * cos(huehue[i][j]-radians(240)) / cos(radians(300)-huehue[i][j]))
#final = cv2.merge((backR, backG, backB))
# The correct order is BGR and not RGB (at the beginning of the funtion: blue = bgr[:,:,0])
final = cv2.merge((backB, backG, backR))
#final = final/360*255
# Convert from flot32 to uint8:
final = np.round(final * 255).astype(np.uint8)
return final
##### Converting to HSI using OpenCV is simple, converting back is difficult #####
def bgr2hsi(bgr):
"""Convert image from BGR color format to HSI color format"""
# Convert from BGR to HSV using OpenCV
hsv = cv2.cvtColor(bgr, cv2.COLOR_BGR2HSV)
# Difference between HSV and HSI:
# In HSV: V = max(R, G, B)
# In HSI: I = (R + G + B)/3
hsi = hsv
hsi[:, :, 2] = np.mean(bgr, 2)
return hsi
bgr = cv2.imread('tree.png')
#hsi = bgr2hsi(bgr)
average = np.mean(np.float32(bgr)/255, 2)
new_bgr = HSI_TO_RGB(average, bgr)
cv2.imshow('new_bgr', new_bgr)
cv2.waitKey(0)
cv2.destroyAllWindows()
注意:我没有尝试优化性能,也没有在寻找RGB到HSI的现有实现。我只是试图更正您发布的代码。