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

一、图像空间的转换

RGB -> HSV      转换公式

opencv学习笔记之六 颜色空间的转换_第1张图片


opencv学习笔记之六 颜色空间的转换_第2张图片

在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 就不会进行比例缩放. 这是一个特殊的优化 。如果原来数组和输出数组的类型相同,这是另一种特殊情形,可以被用于比例缩放和平移矩阵或图像,此时相当于该函数的。










你可能感兴趣的:(opencv学习笔记之六 颜色空间的转换)