2019-05-07 13:49:21 zsc201825 阅读数 313

一 疑问

最近在做相关图片通道从RGB转到HSV时一直存在疑问?在网上找的计算公式都是说:
色调H:0°~360°;
饱和度S:0.0~1.0;
亮度V:0.0~1.0。
但计算公式中:V=max(R,G,B),那V的范围应该是0~255才对啊,怎么会是0-1呢?
另外,OpenCV给出的范围分别如下,怎么和计算公式的范围又不一样呢?
H: 0 — 180
S: 0 — 255
V: 0 — 255
下面就来一一解答上面两个疑问

二 解答

疑问一:V的范围到底是0~255,还是0-1呢?

国内网站上很多博主给出的计算公式其实是不全的,如果你查查OpenCV的官网就会发现,标准计算公式中一开始是把RGB三通道进行了归一化,也就是将R、G、B的值分别归一化到0–1的范围,正确的计算公式如下:
在这里插入图片描述
所以V的取值范围是0–1

疑问二:OpenCV给出的范围为什么和计算公式不一样?

其实,计算公式的后面已经给出了答案,OpenCV中图片存储的深度是8位整数的,0-255之间,所以对计算公式的结果又进行了变换,使HSV的范围在0~255之间。为什么H通道的0-180呢?因为计算公式中H的范围已经在0-360了,所以直接除以了2,使范围缩小在0-180之间就行了。

三 Python代码实现RGB转HSV

from cv2 import cv2
import numpy as np
img0 = cv2.imread('2.jpg')
hsv_img = cv2.cvtColor(img0, cv2.COLOR_BGR2HSV)
h,s,v = cv2.split(hsv_img) #这是OpenCV给出的范围

'''转换为计算公式给出的范围'''
H = h.astype(np.float)*2
S = s.astype(np.float)/255
V = v.astype(np.float)/255
2013-04-14 10:45:10 Armily 阅读数 5092

        最近要处理视频中检测到的阴影,看了一些文章,提到可以利用HSV 三个通道中的一个或者两个组合来进行检测与分割,故小试了一下分离HSV通道,如下为代码,整了一个小时,才显示正确。      

       HSV颜色空间是描述比RGB更准确的颜色感知颜色联系,并在计算上更简单。从RGB颜色空间转换到HSV颜色空间在OpenCV中是如下实现的: 

        

    其中的RGB图像不管是8位的,还是16位的,首先需要将其统统转换成浮点型的,即其值在0~1之间。因此转换后的VS也属于0~1H属于0~360度。

 

#include "stdafx.h"
#include "cv.h"
#include "cxcore.h"
#include "highgui.h"
#include "cvaux.h"

int _tmain(int argc, _TCHAR* argv[])
{
 IplImage* src = NULL;
 IplImage* floatsrc = NULL;
 IplImage* floathsv = NULL;
 IplImage* floatimgH = NULL;
 IplImage* floatimgS = NULL;
 IplImage* floatimgV = NULL;

 cvNamedWindow( "src", 1 );
    cvNamedWindow( "HSV", 1 );
 cvNamedWindow( "H通道", 1 );
 cvNamedWindow( "S通道", 1 );
 cvNamedWindow( "V通道", 1 );

 src = cvLoadImage( "D:\\lena.jpg", -1);

 CvSize size = cvGetSize( src );
    
 //先将图像转换成float型的
 floatsrc = cvCreateImage( size, IPL_DEPTH_32F, 3 );
 floathsv = cvCreateImage( size, IPL_DEPTH_32F, 3 );
 floatimgH = cvCreateImage( size, IPL_DEPTH_32F, 1 );
 floatimgS = cvCreateImage( size, IPL_DEPTH_32F, 1 );
 floatimgV = cvCreateImage( size, IPL_DEPTH_32F, 1 );

 //将src从8位转换到32位的float型
 cvConvertScale( src, floatsrc, 1.0/255.0, 0 );

 //将float型图像 从BGR转换到HSV  如果需要转换到其他的颜色空间 那么改变CV_BGR2HSV即可
 //cvCvtColor要求两个参数的类型必须完全相同,所以要转为float型
 cvCvtColor( floatsrc, floathsv, CV_BGR2HSV);

 //将三通道图像 分解成3个单通道图像,H对应的通道时0,S、V对应的通道时1和2
 //cvCvtPixToPlane(picHSV, h_plane, s_plane, v_plane, 0);
 cvSplit( floathsv, floatimgH, floatimgS, floatimgV, 0);

 cvShowImage( "src", src );
 cvShowImage( "HSV", floathsv );
 cvShowImage( "H通道", floatimgH );
 cvShowImage( "S通道", floatimgS );
 cvShowImage( "V通道", floatimgV );
 

 cvWaitKey( 0 );

 cvReleaseImage( &src );
 cvReleaseImage( &floathsv );
 cvReleaseImage( &floatimgH );
 cvReleaseImage( &floatimgS );
 cvReleaseImage( &floatimgV );

 return 0;
}


    

 

      

2016-01-25 09:20:31 duan19920101 阅读数 1010

将图像分离成HSV空间,并显示HSV空间的每个通道。

 Rect select;
 vector<int> mv;
 capture >> frame;
cvtColor(frame, gray, CV_BGR2GRAY);
cvtColor(frame, gray, COLOR_BGR2GRAY);//使用灰度图进行检测
 /****计算目标模板的直方图特征****/
//在此之前先定义好target_img,然后这样赋值也行,要学会Mat的这个操作
 Mat target_img = Mat(hsv, select);
split(hsv, mv);
imshow("src", hsv);
imshow("H", mv[0]);
 imshow("S", mv[1]);
imshow("V", mv[2]);
calcHist(&target_img, 1, channels, Mat(), target_hist, 3, hist_size, ranges);
 normalize(target_hist, target_hist);



2014-05-01 22:35:25 dashen0 阅读数 1215

            刚刚把去年写过的几篇博文下架了,感觉没下什么功夫在上面,不太值得小伙伴们费神,干脆全部删掉,重新开始嘛酷

        这学期我们大智能开始第一波专业课,基于Opencv下的计算机视觉处理,感觉比较有趣,希望通过不断的学习能够在日后做出自己喜欢的作品。

        这次博文属于我的第一个课程实验,初次接触,印象最为深刻。

       

1)初次接触

这是脑与科学的第一个实验,看到实验内容时感觉无从下手,因为自己只是刚刚把Opencv库函数装载好,只会一个当初搭建环境时助教给的小程序里面的cvShowImage显示图像函数,感觉要坑;

2)尝试解决

起初,感觉自己学了一年多编程了,自我感觉良好,觉得看看相关教程就可以轻松解决,于是乎,拿起

 

<!--EndFragment-->一顿看,结果看的自己一头雾水,自信心受挫;

3)求助度娘

没办法,怀着忐忑不安的心情,点进了百度,一下子找到了很多相关的文章,从中copy了一份分离R/G/B单通道的,启动调试,竟然成功了;

4)然后呢

相信除了少数技术大神,许多人都会想我一样寻求度娘的帮助,但是,接下来的问题,不同人会有不同的后续。。。。。。

next>>

 

许多小朋友往往找到自己所需的答案后,就不再继续深入研究,这样做很不好,不能知其然而不知其所以然。

 

首先,我把程序里面出现的函数,全部转到函数声明,然后寻找其头文件,查看它们的源代码,下面先罗列一下本次直言所遇到的函数(简单的忽略)

 

 

 

cvLoadImage("F:\\Fruits.jpg",1);//载入图像,注意此处1为正数//表示作为三通道图像载入

 

 

 

cvCreateImage(size,depth,channels) //函数,depth 图像元素的位深//,IPL_DEPTH_8U 表示无符号8位整型

 

cvSplit( const CvArr* src,CvArr* dst0,CvArr* dst1,CvArr* dst2,CvArr* dst3 )

 

//复制多通道src图像的各个通道到单通道图像//dst0,dst1,dst2dst3

 

cvMerge( const CvArr* src0, const CvArr* src1,const CvArr* src2, const CvArr* src3,CvArr* dst )

 

//cvSplit相反,将3个单通道合成为一个多通道图像

 

 

 

cvReleaseImage( IplImage** image )

 

//销毁已定义的image指针变量,释放占用内存空间

 

cvCvtColor(img,hsv,CV_BGR2HSV)

 

//实现RGB颜色向HSV,HSI等颜色空间的转换

 

 

 

看完这些函数,虽然已解释的很详细,但毕竟是被封装过的,许多内部原理不可能完全理解,下面,我们再来仔细研究RBG——HSV

 

模型问题

 

1. RGB模型。

 

三维坐标:

 

 

原点到白色顶点的中轴线是灰度线,rgb三分量相等,强度可以由三分量的向量表示。

 

RGB来理解色彩、深浅、明暗变化:

 

色彩变化: 三个坐标轴RGB最大分量顶点与黄紫青YMC色顶点的连线

 

深浅变化:RGB顶点和CMY顶点到原点和白色顶点的中轴线的距离

明暗变化:中轴线的点的位置,到原点,就偏暗,到白色顶点就偏亮

PS: 光学的分析

 

三原色RGB混合能形成其他的颜色,并不是说物理上其他颜色的光是由三原色的光混合形成的,每种单色光都有自己独特的光谱,如黄光是一种单色光,但红色与绿色混合能形成黄色,原因是人的感官系统所致,与人的生理系统有关。

 

只能说将三原色光以不同的比例复合后,对人的眼睛可以形成与各种频率的可见光等效的色觉。

 

2. HSV模型

 

倒锥形模型:

 



 

HSV模型的圆锥表示适合于在一个单一物体中展示整个HSV色彩空间。

 

这个模型就是按色彩、深浅、明暗来描述的。

 

H是色彩

 

S是深浅, S = 0时,只有灰度

 

V是明暗,表示色彩的明亮程度,但与光强无直接联系(意思是有一点点联系吧)。

 

RGBHSV的联系

 

转换表达式:

 


    
    
    
    效果图

 

 

 还不错~~

 

 实现了单通道的分离;

 

     不过我最得意的还是自己找的对象图片...

    

    代码附上

 

 

#include "stdafx.h"
#include"highgui.h"
#include"cv.h"
#include<vector>
using namespace std;
using namespace cv;
int main()
{
	//载入图像
	IplImage* img=cvLoadImage("F:\\Fruits.jpg",1);
	//cvCreateImage(size,depth,channels)函数,depth 图像元素的位深度,IPL_DEPTH_8U 表示无符号8位整型
	IplImage* Bimg=cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1);//1为有1个通道
	IplImage* Gimg=cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1);
	IplImage* Rimg=cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1);

	IplImage* pImg1=cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,3);//3为有3个通道
	IplImage* pImg2=cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,3);
	IplImage* pImg3=cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,3);
	//将RGB图像分离
	//cvSplit( const CvArr* src,CvArr* dst0,CvArr* dst1,CvArr* dst2,CvArr* dst3 )函数
	//复制src的各个通道到图像dst0,dst1,dst2和dst3中
	cvSplit(img,Bimg,Gimg,Rimg,0);
	//目标图像必须与源图像在大小和数据类型上匹配
	//输入多通道,输出为B,G,R单通道

	//在合成之前需要清零
	cvSetZero(pImg1);
	cvSetZero(pImg2);
	cvSetZero(pImg3);
	//将三个通道合成
	//输入参数为B,G,R单通道,最后一个为输出
	//cvMerge( const CvArr* src0, const CvArr* src1,const CvArr* src2, const CvArr* src3,CvArr* dst );
	cvMerge(Bimg,0,0,0,pImg3);
	cvMerge(0,Gimg,0,0,pImg2);
	cvMerge(0,0,Rimg,0,pImg1);
	
	cvNamedWindow("RGB",1);
	cvShowImage("RGB",img);

	cvNamedWindow("R",1);
	cvShowImage("R",pImg1);

	cvNamedWindow("G",1);
	cvShowImage("G",pImg2);

	cvNamedWindow("B",1);
	cvShowImage("B",pImg3);

	//HSV图像处理
	IplImage* hsv=cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,3);

	//将RGB图像转为HSV图像的函数
	cvCvtColor(img,hsv,CV_BGR2HSV);

	IplImage* Himg=cvCreateImage(cvGetSize(hsv),IPL_DEPTH_8U,1);
	IplImage* Simg=cvCreateImage(cvGetSize(hsv),IPL_DEPTH_8U,1);
	IplImage* Vimg=cvCreateImage(cvGetSize(hsv),IPL_DEPTH_8U,1);

	IplImage* HSV1=cvCreateImage(cvGetSize(hsv),IPL_DEPTH_8U,3);//3个通道
	IplImage* HSV2=cvCreateImage(cvGetSize(hsv),IPL_DEPTH_8U,3);
	IplImage* HSV3=cvCreateImage(cvGetSize(hsv),IPL_DEPTH_8U,3);
	//用法同上
	cvSplit(hsv,Vimg,Simg,Himg,0);

	cvNamedWindow("V",1);
	cvShowImage("V",Vimg);

	cvNamedWindow("S",1);
	cvShowImage("S",Simg);

	cvNamedWindow("H",1);
	cvShowImage("H",Himg);

	cvNamedWindow("HSV",1);
	cvShowImage("HSV",hsv);

	cvWaitKey(0);
	//RGB RELEASE
	cvReleaseImage(&img);
	cvReleaseImage(&Rimg);
	cvReleaseImage(&Gimg);
	cvReleaseImage(&Bimg);

	cvReleaseImage(&pImg1);
	cvReleaseImage(&pImg2);
	cvReleaseImage(&pImg3);
	//HSV RELEASE
	cvReleaseImage(&hsv);
	cvReleaseImage(&Himg);
	cvReleaseImage(&Simg);
	cvReleaseImage(&Vimg);

	cvReleaseImage(&HSV1);
	cvReleaseImage(&HSV2);
	cvReleaseImage(&HSV3);

	return 0;
}


 

<!--EndFragment-->

<!--EndFragment-->

<!--EndFragment-->

 

2018-03-22 22:12:20 lanmengyiyu 阅读数 2569

在图像处理中,通常情况下我们不会直接对RGB图像做处理,这主要是因为RGB与人类的视觉感知相差较远,而HSV就是常用的色彩空间。

HSV分别指的是色相/饱和度/明度(Hue, Saturation, Value),对于不同的问题我们通常采用不同的通道来处理。当然最为通用的方法是使图像变为灰度图,直接对灰度图做处理。在早期图像质量评价领域等多个领域,都是这样来做。但是对于某些特定问题,需要具体问题具体分析。

比如,某些由于光照不同造成的视觉感知不同的场景下,我们通常用Value这个通道进行计算,通过计算梯度,可以较好的提取物体边缘。

再比如某些场景下,前景饱和度较高,背景采用饱和度较低的颜色来衬托前景,这时Saturation这个通道的信息就非常有用了。

再比如,在某些室内场景下,风格较为单一,一般一个物体只有一种颜色,这时候Hue这个通道就显得尤为重要了。

总之,HSV色彩空间在图像处理领域应用非常广泛,一般通过采用合适的通道就能完成大多数图像预处理工作。

彩色图像处理

阅读数 32

没有更多推荐了,返回首页