HSV颜色空间下的图片相似性计算(python版)

HSV颜色空间下的图片相似性计算(python版)

由于,论文需要对两个图片的亮度值进行比较。因为,RGB的局限性,所以选择了在HSV的颜色空间中进行计算。虽然,opencv中自带有对直方图的计算方式,但是由于HSV的特殊性。因此,无论我在C++中获得的结果还是python中获得的结果,都有点怪怪的不太正常。所以,想到了自己写一个算法来实现hsv颜色空间的图片相似性计算,当然也可以单独对H,S,V的距离分别单独计算。本文就重点关注两张图片中的V值相似性值。
本文所有用的HSV三维空间坐标转换主要参考[WKM_WannaKnowMore][1]的博客。

  • RGB与HSV的转换
  • python多维矩阵转换为向量数组
  • HSV三维空间坐标计算公式
  • 具体代码实现

RGB与HSV的转换

对于RGB颜色空间到HSV颜色空间的转换,网上有很多代码都可以作为参考。并且由于读入图片方式的不同,其转换的方式也不同。总结来说就是,方法不唯一,看个人选择。给出一种本文的实现方式。

python实现图片读入和颜色空间转换:

import math
import cv2  
import numpy as np  
from matplotlib import pyplot as plt
import matplotlib.mlab as mlab  

img = cv2.imread('~/target1.jpg',cv2.IMREAD_COLOR)
HSV = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

多维矩阵转换为向量数组

由于,第一步我们将RGB颜色空间转换为HSV后得到的是多维的矩阵格式。而在python中,无论是画直方图还是接下来我们需要使用的欧几里得距离计算都需要向量表示。因此,在这一步我们需要对第一步获得结果进行处理,是的最终的表示结果是向量格式。
直接给出代码:

H, S, V = cv2.split(HSV)
aH = np.array(H).flatten()
aS = np.array(S1).flatten()
aV = np.array(V).flatten()

HSV三维空间坐标计算公式

在斜边长R,底面圆半径为r,高为h的HSV圆锥体内,以地面圆心为原点,H=0为x轴正方向建立坐标轴。那么色值是(H,S,V)的点的三维坐标(x,y,z)是

xyz=rVScosH=rVSsinH=h(1V) x = r ∗ V ∗ S ∗ c o s H y = r ∗ V ∗ S ∗ s i n H z = h ∗ ( 1 − V )

具体代码实现:

x1 = r * V1[i] * S1[i] * math.cos(H1[i] / 180.0 * math.pi);
y1 = r * V1[i] * S1[i] * math.sin(H1[i] / 180.0 * math.pi);
z1 = h * (1 - V1[i]);

具体代码实现

import math
import cv2  
import numpy as np  
from matplotlib import pyplot as plt
import matplotlib.mlab as mlab  

img1 = cv2.imread('/home/*/result/target1.jpg',cv2.IMREAD_COLOR)

HSV1 = cv2.cvtColor(img1, cv2.COLOR_BGR2HSV)
aH1, aS1, aV1 = cv2.split(HSV1)
H1 = np.array(aH1).flatten()
S1 = np.array(aS1).flatten()
V1 = np.array(aV1).flatten()

# img2 = cv2.imread('/home/*/allAreaColor/result1.jpg',cv2.IMREAD_COLOR)
img2 = cv2.imread('/home/*/localColor/result1.jpg',cv2.IMREAD_COLOR)

HSV2 = cv2.cvtColor(img2, cv2.COLOR_BGR2HSV)
aH2, aS2, aV2 = cv2.split(HSV2)
H2 = np.array(aH2).flatten()
S2 = np.array(aS2).flatten()
V2 = np.array(aV2).flatten()

R = 100.0;
angle = 30.0;
h = R * math.cos(angle / 180 * math.pi);
r = R * math.sin(angle / 180 * math.pi);

sum = 0.0
for i in range(0, len(H1)):
    x1 = r * V1[i] * S1[i] * math.cos(H1[i] / 180.0 * math.pi);
    y1 = r * V1[i] * S1[i] * math.sin(H1[i] / 180.0 * math.pi);
    z1 = h * (1 - V1[i]);

    x2 = r * V2[i] * S2[i] * math.cos(H2[i] / 180.0 * math.pi);
    y2 = r * V2[i] * S2[i] * math.sin(H2[i] / 180.0 * math.pi);
    z2 = h * (1 - V2[i]);

    dx = x1 - x2;
    dy = y1 - y2;
    dz = z1 - z2;

    sum = sum + dx * dx + dy * dy + dz * dz

eucli_dean = math.sqrt(sum)
print eucli_dean
  • 5
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值