将ROI区域继续划分成4*4小格,求取每4小格组成的1个box区域的Hue(色调)通道直方图

该博客介绍了如何使用OpenCV计算图像ROI区域内的4*4小格组成的box区域的Hue通道直方图。通过遍历窗口并计算每个2*2 box的直方图,再进行比较和归一化,最终生成一个置信图。

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

#pragma once
#include <vector>
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;

class WinBox
{
public:
	WinBox();
	vector<Mat> computeHist(Mat& win, Size box);
	Mat confidence(Mat& img, Size box, vector<Mat>& winHist, int scale = 1, int stride = 1);

private:
	int histSize[2];		//bin数量,声明成数组形式
	float hranges[2];		//直方图的最小值与最大值
	float sranges[2];		//直方图的最小值与最大值
	const float* ranges[2];	//hranges的地址值要赋给ranges[0]
	int channels[2];		//通道

};
#include "WinBox.h"

WinBox::WinBox()
{
	histSize[0] = 30;			histSize[1] = 40;
	hranges[0]  = 0;			hranges[1]  = 180;
	sranges[0]  = 0;			sranges[1]  = 255;
	ranges[0]   = hranges;		ranges[1]   = sranges;
	channels[0] = 0;			channels[1] = 1;
}

//计算给定窗口win的分块直方图,并保存到winHist中
vector<Mat> WinBox::computeHist(Mat& win, Size box)
{
	vector<Mat> winHist;
	for (int i = 0; i < 3; ++i)
	{
		for (int j = 0; j < 3; ++j)
		{
			//从左上开始遍历2*2 box小块
			Rect rect(j*box.width, i*box.height, 2*box.width, 2*box.height);
			Mat box = win(rect), boxHist;
			calcHist(&box, 1, channels, Mat(), boxHist, 2, histSize, ranges);
			normalize(boxHist, boxHist, 0.0, 1.0, NORM_MINMAX);
			winHist.push_back(boxHist);
		}
	}
	return winHist;
}

//读取下一幅完整图像,用窗口win遍历图像(步长为1像素)
//计算当前窗口win下的直方图(9个),并和上幅图像得到的直方图(9个)依次进行对比
//将对比结果求均值,归一化,作为灰度值写入置信图的一个像素点
Mat WinBox::confidence(Mat& img, Size box, vector<Mat>& winHist, int scale, int stride)
{
	//初始化矩形区域(也就是win大小)
	Rect rect(0, 0, 4*box.width, 4*box.height);	
	
	//用窗口扫描图像
	vector<vector<double>> row_size;
	for (int i = 0; i < img.rows; i += stride)
	{
		if (i+4*box.height > img.rows) break;
		vector<double> every_row;
		for (int j = 0; j < img.cols; j += stride)
		{
			Rect rect_temp = rect + Point(j,i);
			if (static_cast<int>(rect_temp.br().x) > img.cols) break;
			else
			{
				Mat winTemp = img(rect_temp);
				vector<Mat> winHistTemp = computeHist(winTemp, box);//计算所有2*2 box区域直方图

				double sum = 0;		//相似度的和
				for (int t = 0; t < 9; ++t)
				{
					double value = cv::compareHist(winHist[t], winHistTemp[t], 0);
					if (value < 0) value = 0;
					sum += value;
				}
				sum /= 9.0;			//求均值
				sum *= 255.0;
				every_row.push_back(sum);
			}
		}
		row_size.push_back(every_row);
	}

	int nr = row_size.size();
	int nc = row_size[0].size();
	Mat backproj = Mat::zeros(nr, nc, CV_8UC1);	//置信图

	for (int i = 0; i < nr; ++i)
	{
		uchar* data = backproj.ptr<uchar>(i);
		for (int j = 0; j < nc; ++j)
			data[j] = static_cast<uchar>(row_size[i][j]);
	}

	//调整置信图
	normalize(backproj, backproj, 0.0, 255.0, NORM_MINMAX);
	resize(backproj, backproj, Size(img.cols*scale,img.rows*scale), 0, 0, 1);
	return backproj;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值