【图像处理】:HSV

**1.图像相似性计算

HSV模型
在这里插入图片描述
HSV颜色检测:https://www.jianshu.com/p/33af63a63a12
①色调H(Hue)
用角度度量,取值范围为0°~360°,从红色开始按逆时针方向计算,红色为0°,绿色为120°,蓝色为240°,。它们的补色是:黄色为60°,青色为180°,品红为300°,0°- 359°时颜色会依次变换当角度到达360°时也就是红色,角度也就又回到0°了,所以总共为360°,每变换1°时,色相就会有轻微的变化!如果是顺时针的话这个变换过程会从红色逐渐变换到绿色,在由绿色逐渐变换到蓝色,在由蓝色逐渐变换到红色!逆时针的话就是相反的!
在这里插入图片描述
②饱和度 S(Saturation)
饱和度S表示颜色接近光谱色的程度。一种颜色,可以看成是某种光谱色与白色混合的结果。其中光谱色所占的比例愈大,颜色接近光谱色的程度就愈高,颜色的饱和度也就愈高。饱和度高,颜色则深而艳。光谱色的白光成分为0,饱和度达到最高。通常取值范围为0%~100%,值越大,颜色越饱和。
在这里插入图片描述
③明度V(Value)
明度表示颜色明亮的程度,对于光源色,明度值与发光体的光亮度有关;通常取值范围为0%(黑)到100%(白)。
在这里插入图片描述
————————————————
原文链接:https://blog.csdn.net/bjbz_cxy/article/details/79701006
step1:RGB颜色空间到HSV颜色空间的转换**

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)

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

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

step3:HSV三维空间坐标计算公式
在这里插入图片描述
在斜边长R,底面圆半径为r,高为h的HSV圆锥体内,以地面圆心为原点,H=0为x轴正方向建立坐标轴。那么色值是(H,S,V)的点的三维坐标(x,y,z)是

x=r∗V∗S∗cosH
y=r∗V∗S∗sinH
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

HSV应用

1.demo
https://wenku.baidu.com/view/75617d16346baf1ffc4ffe4733687e21af45ff8d.html

2.cv2.inrange
函数很简单,参数有三个
第一个参数:hsv指的是原图
第二个参数:lower_red指的是图像中低于这个lower_red的值,图像值变为0
第三个参数:upper_red指的是图像中高于这个upper_red的值,图像值变为0
而在lower_red~upper_red之间的值变成255,范围之外的值变成0

函数目的是将介于[lowerb, upperb]间的像素值变成 255,其他变为 0。
参数说明如下:
hsv:指的是原图,但是需要注意图像格式
lowerb:指的是图像中低于这个 lowerb 的值,图像值变为 0
upperb:指的是图像中高于这个 upperb 的值,图像值变为 0
而在 lowerb ~ lowerb 之间的值变成 255
正常读入的 BGR 图像,需要提前转换成 HSV 格式,
原文链接1(Python):https://blog.csdn.net/hihell/article/details/112794364
参考链接2(C++):https://blog.csdn.net/zhangping1987/article/details/74449630

python-opencv获取图片精确hsv的值

import cv2
import numpy as np
from matplotlib import pyplot as plt

image=cv2.imread('hsv.png')
HSV=cv2.cvtColor(image,cv2.COLOR_BGR2HSV)
def getpos(event,x,y,flags,param):
    if event==cv2.EVENT_LBUTTONDOWN: #定义一个鼠标左键按下去的事件
        print(HSV[y,x])

cv2.imshow("imageHSV",HSV)
cv2.imshow('image',image)
cv2.setMouseCallback("imageHSV",getpos)
cv2.waitKey(0)


  • 9
    点赞
  • 101
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
以下是三道Java面试题: 1. 什么是Java中的多态性?请举例说明。 多态性是指同一个方法可以在不同的对象上产生不同的行为。在Java中,多态性通过继承和方法重写来实现。例如,有一个父类Animal和两个子类Dog和Cat,它们都有一个eat()方法。当调用eat()方法时,如果是Dog对象调用,会执行Dog类中的eat()方法;如果是Cat对象调用,会执行Cat类中的eat()方法。 2. 什么是Java中的异常处理机制?请列举几种常见的异常。 Java中的异常处理机制是一种用于处理程序运行时出现的错误或异常情况的机制。常见的异常包括: - NullPointerException:当一个对象引用为null时,调用该对象的方法或访问其属性会抛出该异常。 - ArrayIndexOutOfBoundsException:当访问数组中不存在的索引时,会抛出该异常。 - FileNotFoundException:当尝试打开一个不存在的文件时,会抛出该异常。 - ArithmeticException:当进行除法运算时,除数为0会抛出该异常。 3. 什么是Java中的线程?如何创建和启动一个线程? 线程是程序执行的最小单位,它是进程中的一个执行流。在Java中,可以通过继承Thread类或实现Runnable接口来创建一个线程。创建线程后,可以调用start()方法来启动线程的执行。例如,通过继承Thread类创建一个线程的示例代码如下: ```java public class MyThread extends Thread { public void run() { // 线程执行的代码 } } // 创建并启动线程 MyThread thread = new MyThread(); thread.start(); ```
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时间之里

好东西就应该拿出来大家共享

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值