python自带的opencv的包里面的函数,将图片从rgb转到hsv颜色空间中,分别输出色度(h)饱和度(s)亮度(v)的数值,但是与网上的标准色卡比较,s,v是准确的,但是h老是不准,然后查阅了很多很多资料,猫猫叹气
因为函数搞出来的Hue的范围是0-180所以要搞到实际的0-360的范围很多教程就是直接*2,所以我不知道是不是这里出了甚么问题(捂住大脸)
代码如下:
#用python自带的函数,hue色卡不准,弃用
# -*- coding: utf-8 -*-
import os
import cv2
import os.path
import matplotlib.pyplot as plt # 画图
import numpy as np # 数值计算
import xlsxwriter # EXCEL写入
from PIL import Image # 图像处理
# 写入EXCEL
workbook = xlsxwriter.Workbook(r'C:\Users\admin\Desktop\py\DataOutput.xlsx') # 创建一个Excel文件
worksheet = workbook.add_worksheet('sheetnew') # 创建一个sheet,名为sheetnew
headings = ['demo', 'name', 'avr_h'] # 表头
worksheet.write_row('A1', headings) # headings 写入Excel
# 计算颜色特征数值
n = 2
filepath = r'C:\Users\admin\Desktop\py\pic' # 图像文件所在目录
pathDir = os.listdir(filepath)
for allDir in pathDir: # 遍历文件夹
path = r'C:/Users/admin/Desktop/py/pic/' + allDir
writename = allDir # 图片名称
image = cv2.imread(path)
hsv = cv2.cvtColor(image, cv2.COLOR_RGB2HSV) # RGB转为HSV
H, S, V = cv2.split(hsv)
# opencv中hsv的范围如下:H: [0,180]
# 在做hsv各通道颜色的计算时,常用的hsv范围如下:H:[0,360]
HH = H.astype(np.float) * 2 # 转换范围H->[0-360]
avg_hh = int(np.mean(HH)) # 平均色度
worksheet.write_row('B' + str(n), [writename, avg_hh]) # 写出到EXCEL
worksheet.insert_image('A' + str(n), path) # 输出图片
n = n + 1
workbook.close()
os.startfile(r'C:\Users\admin\Desktop\py\DataOutput.xlsx')
参考的色卡
实际结果(图片Name表示应该的Hue数值)
所以结果和色卡完全没关系好不好!!!
从rgb转到hsv的计算公式找了很多,然后一直没准的,甚至还找到了Paper上面有说两个颜色空间转换过程中会有什么奇点,所以也按照修正后的公式计算了,依然hue是不准的,直到找到了这个公式 https://blog.csdn.net/zhangphil/article/details/106545941
真的是喜极而泣,拖拉了快一个月的hue终于准了,准了,它准了!!!!!!
#encoding:utf-8
#bgr提取再计算,哇撒!!!可以滴!
#参考https://blog.csdn.net/zhangphil/article/details/106545941
#彩图R、G、B的提取
#
import numpy as np
import cv2
image = cv2.imread(r'C:\Users\admin\Desktop\py\pic\283.7.JPG' )
cv2.imshow("Original",image)
cv2.waitKey(0)
#R、G、B分量的提取
'''(B,G,R) = cv2.split(image)#提取R、G、B分量
cv2.imshow("Red",R)
cv2.imshow("Green",G)
cv2.imshow("Blue",B)
cv2.waitKey(0)'''
b,g,r=cv2.split(image)
B=int(np.mean(b))
G=int(np.mean(g))
R=int(np.mean(r))
def rgb2hsv(r, g, b):
r, g, b = r / 255.0, g / 255.0, b / 255.0
mx = max(r, g, b)
mn = min(r, g, b)
m = mx - mn
if mx == mn:
h = 0
elif mx == r:
if g >= b:
h = ((g - b) / m) * 60
else:
h = ((g - b) / m) * 60 + 360
elif mx == g:
h = ((b - r) / m) * 60 + 120
elif mx == b:
h = ((r - g) / m) * 60 + 240
if mx == 0:
s = 0
else:
s = m / mx
v = mx
# 此时h,s,v值范围分别是0-360, 0-1, 0-1,在OpenCV中,H,S,V范围是0-180,0-255,0-255,加上下面代码转换:
H = h
S = s * 255.0
V = v * 255.0
return H, S, V
H,S,V=rgb2hsv(R,G,B)
print(H)
然后色卡(name本来色卡上的Hue与avg_h是一样l )
喜大普奔奔走呼号嚎啕大哭哭什么哭~~~~~~~
以上代码对于纯色图OK但是对于日常图片,来计算非纯色图全图的平均色度,还是要遍历一下全图,然后读取文件图片批量处理一下下呀!!!
# Hue完美符合色卡
import cv2
import numpy as np
# -*- coding: utf-8 -*-
import os
import cv2
import os.path
import matplotlib.pyplot as plt # 画图
import numpy as np # 数值计算
import xlsxwriter # EXCEL写入
from PIL import Image # 图像处理
def rgb2hsv(img):
h = img.shape[0]
w = img.shape[1]
H = np.zeros((h,w),np.float32)
S = np.zeros((h, w), np.float32)
V = np.zeros((h, w), np.float32)
b,g,r = cv2.split(img)
r, g, b = r/255.0, g/255.0, b/255.0
for i in range(0, h):
for j in range(0, w):
mx = max((b[i, j], g[i, j], r[i, j]))
mn = min((b[i, j], g[i, j], r[i, j]))
m = mx-mn
if mx == mn:
H[i, j] = 0
elif mx == r[i, j]:
if g[i, j] >= b[i, j]:
H[i, j] = (60 * ((g[i, j]) - b[i, j]))/ m
else:
H[i, j] = (60 * ((g[i, j]) - b[i, j])) / m +360
elif mx == g[i, j]:
H[i, j] = 60 * ((b[i, j]) - r[i, j]) / m + 120
elif mx == b[i, j]:
H[i, j] = 60 * ((r[i, j]) - g[i, j]) / m + 240
if mx == 0:
S[i, j] = 0
else:
S[i, j] = m /mx
V[i,j]=mx
return H, S, V
# 写入EXCEL
workbook = xlsxwriter.Workbook(r'C:\Users\admin\Desktop\py\DataOutput.xlsx') # 创建一个Excel文件
worksheet = workbook.add_worksheet('sheetnew') # 创建一个sheet,名为sheetnew
headings = ['demo', 'name', 'avr_h'] # 表头
worksheet.write_row('A1', headings) # headings 写入Excel
# 计算颜色特征数值
n = 2
filepath = r'C:\Users\admin\Desktop\py\pic' # 图像文件所在目录
pathDir = os.listdir(filepath)
for allDir in pathDir: # 遍历文件夹
path = r'C:/Users/admin/Desktop/py/pic/' + allDir
writename = allDir # 图片名称
image = cv2.imread(path)
h, s, v = rgb2hsv(image)
'''cv2.imshow("h", h)
cv2.imshow("s", s)
cv2.imshow("v", v)
merged = cv2.merge([h, s, v]) # 前面分离出来的三个通道
cv2.imshow("hsv", merged)
cv2.waitKey(0)
cv2.destroyAllWindows()'''
#HH = h.astype(np.float) * 2 # 转换范围H->[0-360]
avg_hh = int(np.mean(h)) # 平均色度
worksheet.write_row('B' + str(n), [writename, avg_hh]) # 写出到EXCEL
worksheet.insert_image('A' + str(n), path) # 输出图片
n = n + 1
workbook.close()
os.startfile(r'C:\Users\admin\Desktop\py\DataOutput.xlsx')
参考链接
hsv计算公式:
https://blog.csdn.net/zhangphil/article/details/106545941
色卡来源:(但是颜色在色度环上的范围虽然可供参考但我认为不是特别准欸,后面我的发现请挪步下一篇我的博文嘻嘻嘻嘻嘻)
https://blog.csdn.net/Taily_Duan/article/details/51506776?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522161121134716780261959143%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=161121134716780261959143&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_v2~rank_v29-1-51506776.first_rank_v2_pc_rank_v29&utm_term=%E5%B0%8F%E4%B8%AB%E5%A4%B4%20hsv%20hue&spm=1018.2226.3001.4187