编制直方图程序。
要求:手工输入源图像,计算直方图,输出显示直方图和源图像。(注:不要用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.结果展示
也不知道结果正不正确,本人水平有限,请大家多多指教!