通过阅读源代码后,将源代码进行改写,实现自己的直方图均衡化
(1)equalizeHist.h文件
#ifndef EQUALIZEHIST_H
#define EQUALIZEHIST_H
#include<iostream>
#include<opencv2\core\core.hpp>
void myEqualizeHist(cv::Mat &src, cv::Mat &dst);
#endif
(2)equalizeHist.cpp文件
#include"equalizeHist.h"
void myEqualizeHist(cv::Mat &src, cv::Mat &dst)
{
if (src.empty())
{
return;
}
CV_Assert(src.type() == CV_8UC1);
cv::Mat _src(src.size(),src.type());
src.copyTo(_src);
int hist[256] = { 0, };
int lut[256];
cv::Range heightRange(0, _src.rows);
const size_t sstep = _src.step;
int width = _src.cols;
int height = heightRange.end - heightRange.start;
if (_src.isContinuous())
{
width *= height;
height = 1;
}
for (const uchar* ptr = _src.ptr<uchar>(heightRange.start); height--; ptr += sstep)
{
int x = 0;
for (; x <= width - 4; x += 4)
{
int t0 = ptr[x], t1 = ptr[x + 1];
hist[t0]++; hist[t1]++;
t0 = ptr[x+2], t1 = ptr[x + 3];
hist[t0]++; hist[t1]++;
}
for (; x < width; ++x)
{
hist[ptr[x]]++;
}
}
int i = 0;
while (!hist[i]) ++i;
int total = (int)_src.total();
if (hist[i] == total)
{
dst.setTo(i);
return;
}
float scale = (256-1.f) / (total - hist[i]);
int sum = 0;
for (lut[i++] = 0; i < 256; ++i)
{
sum += hist[i];
lut[i] = cv::saturate_cast<uchar>(sum*scale);
}
cv::Range heightRange1(0, _src.rows);
const size_t dstep = dst.step;
int height1= heightRange1.end - heightRange1.start;
int width1= _src.cols;
if (_src.isContinuous() && dst.isContinuous())
{
width1 *= height1;
height1 = 1;
}
const uchar* sptr1 = _src.ptr<uchar>(heightRange1.start);
uchar* dptr1 = dst.ptr<uchar>(heightRange1.start);
for (; height1--; sptr1 += sstep, dptr1 += dstep)
{
int x = 0;
for (; x <= width1 - 4; x += 4)
{
int v0 = sptr1[x];
int v1 = sptr1[x + 1];
int x0 = lut[v0];
int x1 = lut[v1];
dptr1[x] = (uchar)x0;
dptr1[x + 1] = (uchar)x1;
v0 = sptr1[x+2];
v1 = sptr1[x + 3];
x0 = lut[v0];
x1 = lut[v1];
dptr1[x+2] = (uchar)x0;
dptr1[x+3] = (uchar)x1;
}
for (; x < width1; ++x)
{
dptr1[x] = (uchar)lut[sptr1[x]];
}
}
}
(3)主程序main.cpp
#include"equalizeHist.h"
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\imgproc\imgproc.hpp>
int main()
{
cv::Mat img = cv::imread("1.jpg");
cv::imshow("原图像",img);
cv::Mat grayImg;
cv::cvtColor(img, grayImg, CV_BGR2GRAY);
cv::imshow("灰度图", grayImg);
cv::Mat equalGrayImg(grayImg.size(), grayImg.type());
myEqualizeHist(grayImg, equalGrayImg);
imshow("均衡化后的灰度图",equalGrayImg);
cv::waitKey(0);
return 0;
}
结果:
原图像:
灰度图:
均衡化后的图像: