C++编制直方图程序

编制直方图程序。
要求:手工输入源图像,计算直方图,输出显示直方图和源图像。(注:不要用OpenCV自带函数)

原理如下:

 代码实现:

1.先看类声明

因为后期要显示红绿蓝三个通道的直方图,因此在vs中调用matlab的bar函数,友友们可以看下在vs中如何配置使用matlab

#include<iostream>
#include<string>

#include<opencv2/core/core.hpp>
#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
#include"engine.h"
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "libeng.lib")
#pragma comment(lib, "libmx.lib")
#pragma comment(lib, "libmat.lib")

using namespace std;
using namespace  cv;
class pHist
{
public:
	pHist();
	~pHist();
	void readImage(string filename);
	void calHist();
	void changeToGray();//转为灰度图像
	void calAccumulate();//计算累计分布,均衡化直方图
	void show();
private:
	Mat image;
	Mat gray_image;
	Mat out;
	int channels;
	double **Hist;
};

2.读取图像文件

void pHist::readImage(string filename)
{
	image = imread(filename);
	this->channels = image.channels();
	Hist = new double*[channels];
	for (int i = 0; i < channels; i++) {
		Hist[i] = new double[256];
	}
	for (int i = 0; i < channels; i++) {
		for (int j = 0; j <= 255; j++) {
			Hist[i][j] = 0;
		}
	}
}

3.计算每个通道每个灰度级对应的像素个数并归一化

void pHist::calHist()
{
	int rows = image.rows;
	int cols = image.cols;
	for (int i = 0; i < rows; i++) {
		for (int j = 0; j < cols; j++) {
			Hist[0][image.at<Vec3b>(i, j)[0]]++;
			Hist[1][image.at<Vec3b>(i, j)[1]]++;
			Hist[2][image.at<Vec3b>(i, j)[2]]++;
		}
	}
	int piex_number = rows * cols;
	for ( int i = 0; i < channels; i++) {
		for ( int j = 0; j <= 255; j++) {
			Hist[i][j] /= piex_number;
		}
	}
}

4.将结果以图像展示(调用matlab函数)

void pHist::show()
{
	namedWindow("原始图像");
	imshow("原始图像", image);
	Engine* ep;
    mxArray* x1 = NULL;
	mxArray* y1 = NULL;
	mxArray* y2 = NULL;
	mxArray* y3 = NULL;
	if ((ep = engOpen("")) == NULL)
	{
     cout<<"Engine Fail"<<endl;
	}
	x1 = mxCreateDoubleMatrix(1, 256, mxREAL);
	y1 = mxCreateDoubleMatrix(1, 256, mxREAL);
	y2 = mxCreateDoubleMatrix(1, 256, mxREAL);
	y3 = mxCreateDoubleMatrix(1, 256, mxREAL);
	double x[256];
	for (int i = 0; i < 256; i++) {
		x[i] = i;
	}
	
	memcpy(mxGetPr(x1), x, 256 * sizeof(double));
	memcpy(mxGetPr(y1), Hist[0], 256 * sizeof(double));
	memcpy(mxGetPr(y2), Hist[1], 256 * sizeof(double));
	memcpy(mxGetPr(y3), Hist[2], 256 * sizeof(double));
	engPutVariable(ep, "x", x1);
	engPutVariable(ep, "y1", y1);
	engPutVariable(ep, "y2", y2);
	engPutVariable(ep, "y3", y3);
	engEvalString(ep, "subplot(2,2,1);bar(x, y1);title('R');subplot(2,2,2);bar(x, y2);title('G');subplot(2,2,3);bar(x, y3);title('B');");
	mxDestroyArray(x1);
	mxDestroyArray(y1);
	mxDestroyArray(y2);
	mxDestroyArray(y3);
	getchar();
	engClose(ep);

}

5.结果展示

 也不知道结果正不正确,本人水平有限,请大家多多指教!

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

m0_60434562

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值