色调反向投影找特定的内容

本文探讨了在处理8位图像时,色调H的取值范围限制为0到180的原因,以避免超过uchar类型的255上限。通过调整颜色空间并使用全精度可以获取0-360的完整色调范围。此外,提到了image.type()返回的int值,如cv_8uc3对应的16,详细解释了其在源文件中的定义。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这里的注意的是色调H,其在这里的取值范围为0到180,因为Note this is only done for 8-bit formats. So if you want fullprecision, you can always switch to a 32f format prior to the colorspace conversion, which will yield the full 0-360 hue range.简单来说就是这图为uchar范围在0到255,如果取全范围0到360就会超过256,所以这里用0到180来表示。

至于image.type()返回的int,如果为cv_8uc3返回为16,具体见其源文件的定义。

以下为代码:

// opencv_calcbackproject.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <opencv245.h>

using namespace std;
using namespace cv;


class ColorHistogram  
{  
private:  
	int histSize[3];  
	float hranges[2];  
	const float* ranges[3];  
	int channels[3];  
public:  

	//构造函数  
	ColorHistogram()  
	{  
		histSize[0]= histSize[1]= histSize[2]= 256;  
		hranges[0] = 0.0;  
		hranges[1] = 255.0;  
		ranges[0] = hranges;  
		ranges[1] = hranges;  
		ranges[2] = hranges;  
		channels[0] = 0;  
		channels[1] = 1;  
		channels[2] = 2;  
	}  

	//计算彩色图像直方图  
	Mat getHistogram(const Mat& image)  
	{  
		Mat hist;  

		//BGR直方图  
		hranges[0]= 0.0;      
		hranges[1]= 255.0;  
		channels[0]= 0;   
		channels[1]= 1;   
		channels[2]= 2;   

		//计算  
		calcHist(&image,1,channels,Mat(),hist,3,histSize,ranges);  
		return hist;  
	}  

	//计算颜色的直方图  
	Mat getHueHistogram(const Mat &image)  
	{  
		Mat hist;  
		Mat hue;  
		//转换到HSV空间  
		cvtColor(image,hue,CV_BGR2HSV);  

		//设置1维直方图使用的参数  
		hranges[0] = 0.0;  
		hranges[1] = 180.0;  
		channels[0] = 0;  
		//计算直方图  
		calcHist(&hue,1,channels,Mat(),hist,1,histSize,ranges);  
		return hist;  

	}  

	//减少颜色  
	Mat colorReduce(const Mat &image,int div = 64)  
	{  
		int n = static_cast<int>(log(static_cast<double>(div))/log(2.0));  
		uchar mask = 0xFF<<n;  
		Mat_<Vec3b>::const_iterator it = image.begin<Vec3b>();  
		Mat_<Vec3b>::const_iterator itend = image.end<Vec3b>();  
		//设置输出图像  
		Mat result(image.rows,image.cols,image.type());  
		Mat_<Vec3b>::iterator itr = result.begin<Vec3b>();  
		for(;it != itend;++it,++itr)  
		{  
			(*itr)[0] = ((*it)[0]&mask) + div/2;  
			(*itr)[1] = ((*it)[1]&mask) + div/2;  
			(*itr)[2] = ((*it)[2]&mask) + div/2;  
		}  
		return result;  
	}  

};  




class ContentFinder  
{  
private:  
	float hranges[2];  
	const float* ranges[3];  
	int channels[3];  
	float threshold;  
	Mat histogram;  
public:  
	ContentFinder():threshold(-1.0f)  
	{  
		//所有通道的范围相同  
		ranges[0] = hranges;  
		ranges[1] = hranges;   
		ranges[2] = hranges;  
	}  

	 
	void setThreshold(float t)  
	{  
		threshold = t;  
	}  

	  
	float getThreshold()  
	{  
		return threshold;  
	}  

	//设置参考的直方图  
	void setHistogram(const Mat& h)  
	{  
		histogram = h;  
		normalize(histogram,histogram,1.0);  
	}  

	 
	Mat find(const Mat& image)  
	{  
		Mat result;  
		hranges[0] = 0.0;  
		hranges[1] = 255.0;  
		channels[0] = 0;  
		channels[1] = 1;  
		channels[2] = 2;  

		calcBackProject(&image,1,channels,histogram,result,ranges,255.0);  
		if (threshold>0.0)  
		{  
			cv::threshold(result, result, 255*threshold, 255, cv::THRESH_BINARY);  
		}  

		return result;  
	}  

	
	Mat find(const Mat &image,float minValue,float maxValue,int *channels,int dim)  
	{  
		Mat result;  
		hranges[0] = minValue;  
		hranges[1] = maxValue;  
		for(int i = 0;i < dim;i++)  
		{  
			this->channels[i] = channels[i];  
		}  
		calcBackProject(&image,1,channels,histogram,result,ranges,255.0);  
		if(threshold >0.0)  
			cv::threshold(result,result, 255*threshold,255,THRESH_BINARY);  
		return result;  

	}  
};  

int _tmain(int argc, _TCHAR* argv[])
{
	ColorHistogram hc;
	ContentFinder finder;
	Mat result1;
	Mat image = imread("C:\\Users\\sony\\Desktop\\cloud.jpg");
	Mat imageROI = image(Rect(130, 156, 32, 32));
	Mat imagehist = hc.getHueHistogram(imageROI);
    //归一化直方图 使其在0到1之间
	finder.setHistogram(imagehist);
	/*finder.setThreshold(0.3f);*/
	Mat hsv;  
	cvtColor(image,hsv,CV_BGR2HSV);  
		
	
	//表示通道
	int ch[1] ;
	ch[0] = 0;
	result1 = finder.find(hsv, 0.0f,180.0f,ch,1);  
	imshow("使用色度的结果(1)",result1); 

	waitKey(0);

	return 0;
}

效果图如下:




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值