您的位置:首页 > 运维架构

opencv学习笔记之六 颜色空间的转换

2014-12-21 14:13 411 查看
一、图像空间的转换

RGB -> HSV 转换公式





在openCV中,H取值范围是 0-360,S是 0-1,V是0-255。

本例显示的H的值是0-180,原因是cvCreateImage()中创建的是8位图像深度的图像。存放值范围是0-255,不足360。

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

int _tmain(int argc, _TCHAR* argv[])
{
IplImage* src = cvLoadImage("D:\\PERSONAL\\VC++\\OpenCV\\image\\hyhead4.jpg");
IplImage* img_hsv = cvCreateImage(cvGetSize(src),8,3);
IplImage* img_h = cvCreateImage(cvGetSize(src),8,1);
IplImage* img_s = cvCreateImage(cvGetSize(src),8,1);
IplImage* img_v = cvCreateImage(cvGetSize(src),8,1);

cvCvtColor(src,img_hsv,CV_BGR2HSV);

cvSplit(img_hsv,img_h,img_s,img_v,NULL);

for(int y=0;y<img_h->height;y++)
{
for(int x=0;x<img_h->width;x++)
{
float value = (float)cvGetReal2D(img_h,y,x);//获取单通道图像上该店的值(这里是H的值)
if(value > 178)
{
printf("%f  ",value);
}
}
}

cvNamedWindow("BGR");
cvShowImage("BGR",src);

cvWaitKey(0);

cvReleaseImage(&src);   cvDestroyWindow("BGR");

return 0;
}


H显示为360的代码:思路是将其图像深度改为 F32

IplImage* src = cvLoadImage("D:\\PERSONAL\\VC++\\OpenCV\\image\\hyhead4.jpg");
/*
IplImage* img_hsv = cvCreateImage(cvGetSize(src),8,3);
IplImage* img_h = cvCreateImage(cvGetSize(src),8,1);
IplImage* img_s = cvCreateImage(cvGetSize(src),8,1);
IplImage* img_v = cvCreateImage(cvGetSize(src),8,1);
*/
IplImage* src_float = cvCreateImage(cvGetSize(src),IPL_DEPTH_32F,3);
cvConvertScale(src,src_float,1.0,0); //用于转换数据类型。因子是1.0,偏移是0   详细用法看下面
//把src中RGB的值(int)转换为(float)存放到src_float中

IplImage* img_hsv = cvCreateImage(cvGetSize(src),IPL_DEPTH_32F,3);
IplImage* img_h = cvCreateImage(cvGetSize(src),IPL_DEPTH_32F,1);
IplImage* img_s = cvCreateImage(cvGetSize(src),IPL_DEPTH_32F,1);
IplImage* img_v = cvCreateImage(cvGetSize(src),IPL_DEPTH_32F,1);

<span style="white-space:pre">	</span>//注意此时是对<span style="font-family: Arial, Helvetica, sans-serif;">src_float进行由BGR  ->  HSV的变化</span>
cvCvtColor(src_float,img_hsv,CV_BGR2HSV);//转换src(BGR)为(HSV)存入img_hsv中  元素的值可以是int/float

cvSplit(img_hsv,img_h,img_s,img_v,NULL);

for(int y=0;y<img_h->height;y++)
{
for(int x=0;x<img_h->width;x++)
{
float value = (float)cvGetReal2D(img_h,y,x);//获取单通道图像上该店的值(这里是H的值)
if(value > 358){
printf("%f  ",value);
}
}
}


注解: cvConvertScale()
将src 变为 dst

CVAPI(void) cvConvertScale( const CvArr* src, CvArr* dst, double scale CV_DEFAULT(1), double shift CV_DEFAULT(0) );

src 输入数组.

  dst 输出数组

  scale 比例因子.

  shift 该加数被加到输入数组元素按比例缩放后得到的元素上

  函数 cvConvertScale 有多个不同的目的因此就有多个同义函数(如上面的#define所示)。该函数首先对输入数组的元素进行比例缩放,然后将shift加到比例缩放后得到的各元素上,即: dst(I)=src(I)*scale + (shift,shift,...),最后可选的类型转换将结果拷贝到输出数组。

  多通道的数组对各个通道是独立处理的。

  类型转换主要用舍入和溢出截断来完成。也就是如果缩放+转换后的结果值不能用输出数组元素类型值精确表达,就设置成在输出数组数据轴上最接近该数的值。

  如果 scale=1, shift=0 就不会进行比例缩放. 这是一个特殊的优化 。如果原来数组和输出数组的类型相同,这是另一种特殊情形,可以被用于比例缩放和平移矩阵或图像,此时相当于该函数的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: