首页 > 编程知识 正文

数字图像处理PPT,hsv与rgb检测的优劣

时间:2023-05-05 15:21:37 阅读:108204 作者:586

01 RGB和HSV在介绍RGB图和HSV图的相互转换之前,首先介绍这两种图像。

首先是RGB图像RGB图像是三通道图像,通常用于表示彩色图像,由同一行、列的红(Red )、绿(green )、蓝)三通道数据组成。 例如,对于512行512列RGB图像,红通道为512*512灰度,绿通道为512*512灰度,蓝通道为512*512灰度,相加三通道的数据构成3*512*512的RGB图像

一些常见的可视颜色由三个像素值代码组成,对应于三个通道数据的坐标位置。 例如,对于8比特的RGB图像,各像素值能够取的范围为0~255,如果在某个坐标a中的红、绿、蓝的三个通道的像素值依次为255、255、255,则该点所表示的颜色为白色。

RGB图像是与硬件对应的图像。 也就是说,从彩色照相机的图像传感器输出的原始数据本身包含r、g、b三个通道的数据。 它将三通道的图像数据按一定顺序排列(拜耳排列)输出,上位机通过USB或网络接收传感器传来的数据并解析为RGB图像。 例如,在传感器输出的RG/GB格式的拜耳排列中,其r、g、b数据的排列如下图所示。

其次是HSV图像RGB图像与从照相机传感器输出的原始数据对应,HSV图像与我们人类的直观视觉更一致。 HSV图像还包含相同大小的三个通道的数据: h通道、s通道和v通道。 分别介绍这三个频道。

H通道:H个信道的像素值表示色调,并且取值范围是0到360。 该值的范围可以捕捉为角度,也就是一个闭环的值的范围。 下图:

S通道:S通道中的像素值表示图像的饱和度。 饱和度是指图像中的颜色纯度——图像中混合的颜色越少,饱和度越高,笔直看起来越鲜艳,视觉效果越强。 相反,图像的混合颜色越多,饱和度越低,视觉效果越弱。

例如,在所有可见颜色中,纯红的饱和度最高,也就是说纯红看起来最鲜艳,但是在纯红中混合其他颜色会降低饱和度,使其看起来不那么鲜艳。

s通道像素值的可取范围为0~1,值越大表示饱和度越高。

V通道:V通道的像素值表示图像的亮度,取值范围也是0到1,值越大表示越亮。

因为是由以上介绍可知,RGB图像与硬件输出相对应,而HSV图像则更符合人眼的直观视觉,所以在处理图像时,往往首先将RGB图像转换成HSV图像,在HSV颜色空间中处理图像,在处理结束后将HSV图像转换成RGB图像。

在阐述02 RGB与HSV的互变换原理之前,首先以8位色图为例阐明了RGB图像、HSV图像中各通道像素值的取值范围,对于图像中的任意坐标点,其取值范围如下。

然而,在Opencv中,为了使HSV图像可视化,通常将其像素值变换到0到255间:

RGB转HSV原理转换原理非常简单,对于图像中的任意坐标点,需要将其RGB颜色空间转换为(r,g,b )、HSV颜色空间(h,s,v ),首先将r,g,b值转换为0 ) 1之间

然后计算h、s、v的值:

当通过计算获得的h值小于0时,在该值上加上360,获得最终的h值。

由于Opencv需要可视化HSV图像,因此最后必须将每个值转换为0到255之间。

HSV转RGB原理对于图像中的任意坐标点,RGB颜色空间是(r,g,b ),HSV颜色空间是(h,s,v )。 首先,将可视化图像的h、s、v值分别转换为0~360、0~1、0~1的范围。

那么,r、g、b的计算公式如下。 其中floor表示四舍五入运算。

基于Opencv的RGB和HSV

互相转换

Opencv提供了cvtColor函数,调用该函数可以非常方便地实现不同颜色空间的转换。不过为了可视化,调用该函数得到的HSV图像,其H、S、V三通道的取值范围并不是0~360、0~1、0~1,而是经过转换的0~180、0~255、0~255

void rgb_hsv(void){ //读取原图像 Mat img = imread("000000000902.bmp", CV_LOAD_IMAGE_COLOR); Mat img_hsv; cvtColor(img, img_hsv, CV_BGR2HSV); //将RGB图像转换为HSV图像 Mat img_rgb; cvtColor(img_hsv, img_rgb, CV_HSV2BGR); //将HSV图像转换为RGB图像 imshow("ori rgb", img); imshow("hsv", img_hsv); imshow("rgb", img_rgb); waitKey();}

运行结果:

原图

HSV图像

将HSV图像还原为RGB图像,与原图一致

04 使用C++自己实现HSV与RGB的互相转换

为了加深上述转换公式的理解,我们使用C++自己来实现转换过程。

首先是RGB转换为HSV的代码: void RGB2HSV(Mat img_rgb, Mat &img_hsv){ img_hsv = Mat::zeros(img_rgb.size(), CV_8UC3); for (int i = 0; i < img_rgb.rows; i++) { Vec3b *p0 = img_rgb.ptr<Vec3b>(i); //B--p[0] G--p[1] R--p[2] Vec3b *p1 = img_hsv.ptr<Vec3b>(i); //B--p[0] G--p[1] R--p[2] for (int j = 0; j < img_rgb.cols; j++) { float B = p0[j][0] / 255.0; float G = p0[j][1] / 255.0; float R = p0[j][2] / 255.0; float V = (float)std::max({ B, G, R }); //B/G/R float vmin = (float)std::min({ B, G, R }); float diff = V - vmin; float S, H; S = diff / (float)(fabs(V) + FLT_EPSILON); diff = (float)(60.0 / (diff + FLT_EPSILON)); if (V == B) //V=B { H = 240.0 + (R - G) * diff; } else if (V == G) //V=G { H = 120.0 + (B - R) * diff; } else if (V == R) //V=R { H = (G - B) * diff; } H = (H < 0.0) ? (H + 360.0) : H; p1[j][0] = (uchar)(H / 2); p1[j][1] = (uchar)(S * 255); p1[j][2] = (uchar)(V * 255); } }} 其次是HSV转换为RGB的代码: void HSV2BGR(Mat img_hsv, Mat &img_rgb){ img_rgb = Mat::zeros(img_hsv.size(), CV_8UC3); for (int i = 0; i < img_rgb.rows; i++) { Vec3b *p0 = img_hsv.ptr<Vec3b>(i); //B--p[0] G--p[1] R--p[2] Vec3b *p1 = img_rgb.ptr<Vec3b>(i); //B--p[0] G--p[1] R--p[2] for (int j = 0; j < img_hsv.cols; j++) { float H = p0[j][0] * 2.0; float S = p0[j][1] / 255.0; float V = p0[j][2] / 255.0; float h = H / 60.0; int i = floor(h); float f = h - i; float p = V * (1 - S); float q = V * (1 - f * S); float t = V * (1 - (1 - f) * S); switch (i) { case 0: p1[j][2] = (uchar)(V * 255); p1[j][1] = (uchar)(t * 255); p1[j][0] = (uchar)(p * 255); break; case 1: p1[j][2] = (uchar)(q * 255); p1[j][1] = (uchar)(V * 255); p1[j][0] = (uchar)(p * 255); break; case 2: p1[j][2] = (uchar)(p * 255); p1[j][1] = (uchar)(V * 255); p1[j][0] = (uchar)(t * 255); break; case 3: p1[j][2] = (uchar)(p * 255); p1[j][1] = (uchar)(q * 255); p1[j][0] = (uchar)(V * 255); break; case 4: p1[j][2] = (uchar)(t * 255); p1[j][1] = (uchar)(p * 255); p1[j][0] = (uchar)(V * 255); break; default: p1[j][2] = (uchar)(V * 255); p1[j][1] = (uchar)(p * 255); p1[j][0] = (uchar)(q * 255); break; } } }} 测试代码: void rgb_hsv(void){ Mat img = imread("000000000902.bmp", CV_LOAD_IMAGE_COLOR); Mat img_hsv; //cvtColor(img, img_hsv, CV_BGR2HSV); RGB2HSV(img, img_hsv); Mat img_rgb; //cvtColor(img_hsv, img_rgb, CV_HSV2BGR); HSV2BGR(img_hsv, img_rgb); imshow("ori rgb", img); imshow("hsv", img_hsv); imshow("rgb", img_rgb); waitKey();}

运行结果如下,可以看到,转换结果跟调用Opencv函数的结果是一致的。

HSV图像

将HSV图像还原为RGB图像,与原图一致

欢迎扫码关注本微信公众号,接下来会不定时更新更加精彩的内容,敬请期待~

 

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。