This solution was pasted from the original authors solution. However, to guarantee this will work in the feature, this should be kept as code here:
#ifndef OPENCVUTILS_H
#define OPENCVUTILS_H
#include <iostream>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/imgproc/imgproc_c.h>
#include <opencv2/core/internal.hpp>
void cvEqualizeHist( const CvArr* srcarr, CvArr* dstarr, CvMat* mask )
{
using namespace cv;
CvMat sstub, *src = cvGetMat(srcarr, &sstub);
CvMat dstub, *dst = cvGetMat(dstarr, &dstub);
CV_Assert( CV_ARE_SIZES_EQ(src, dst) && CV_ARE_TYPES_EQ(src, dst) &&
CV_MAT_TYPE(src->type) == CV_8UC1 );
CV_Assert( CV_ARE_SIZES_EQ(src, mask) && CV_MAT_TYPE(mask->type) == CV_8UC1);
CvSize size = cvGetMatSize(src);
if( CV_IS_MAT_CONT(src->type & dst->type) )
{
size.width *= size.height;
size.height = 1;
}
int x, y;
const int hist_sz = 256;
int hist[hist_sz];
memset(hist, 0, sizeof(hist));
for( y = 0; y < size.height; y++ )
{
const uchar* sptr = src->data.ptr + src->step*y;
const uchar* mptr = mask->data.ptr + mask->step*y;
for( x = 0; x < size.width; x++ )
if (mptr[x]) hist[sptr[x]]++;
}
float scale = 255.f/(cvCountNonZero(mask));
int sum = 0;
uchar lut[hist_sz+1];
for( int i = 0; i < hist_sz; i++ )
{
sum += hist[i];
int val = cvRound(sum*scale);
lut[i] = CV_CAST_8U(val);
}
lut[0] = 0;
cvSetZero(dst);
for( y = 0; y < size.height; y++ )
{
const uchar* sptr = src->data.ptr + src->step*y;
const uchar* mptr = mask->data.ptr + mask->step*y;
uchar* dptr = dst->data.ptr + dst->step*y;
for( x = 0; x < size.width; x++ )
if (mptr[x]) dptr[x] = lut[sptr[x]];
}
}
void equalizeHist(cv::InputArray _src, cv::OutputArray _dst, cv::InputArray _mask = cv::noArray())
{
using namespace cv;
Mat src = _src.getMat().clone();
_dst.create( src.size(), src.type() );
Mat dst = _dst.getMat();
Mat mask;
if (_mask.empty()) mask = Mat::ones(src.size(), CV_8UC1);
else mask = _mask.getMat();
CvMat _csrc = src, _cdst = dst, _cmask = mask;
cvEqualizeHist( &_csrc, &_cdst, &_cmask);
}
#endif
Yes there is, download the source code, find yourself the implementation of equalizeHist, adapt it to your needs and rebuilt openCV on your system. Or you could do the following using the openCV functionality:
However, this will only work with rectangular regions, but it could suit your needs.
And how about using MaskROI with Mat? Can I form a non-rectangular Region Of Interest?
Not for this equalize hist, because the function requires a data matrix and just uses pixel intensities. It is not possible to ignore values there.
I found implementation of equalizeHist(src, dst, mask) on the net: https://github.com/hengli/camodocal/blob/cd2044ace16c0847c132582034cefacd76122f2b/src/gpl/OpenCVUtils.h
Resolved ))
It might be a good idea to submit this solution as a pull request to openCV. I do think many people will enjoy this new functionality!