[英]Is there any function equivalent to Matlab's imadjust in OpenCV with C++?
我习惯于使用imadjust
在 Matlab 中进行对比度增强。 OpenCV 中是否有任何等效的功能?
谷歌搜索提供了关于亮度和对比度增强的OpenCV 文档,但它使用了可能效率低下的循环。 即使我们通过使用Matrix 表达式使其高效,它也不等同于imadjust所做的。
OpenCV 中是否有任何内置函数或该任务的任何有效方法?
我看到了相关的帖子,但要么链接到我上面提到的 OpenCV 文档,要么建议使用 Histogram Equalization and thresholding 。 我更喜欢imadjust
直方图均衡和阈值似乎并没有执行对比度增强。
对此的任何帮助表示赞赏。
OpenCV 中没有内置解决方案来执行直方图拉伸,但您可以在循环中轻松完成。
imadjust
允许选择上限和下限的容差,或直接选择边界,因此您需要比简单的 for 循环更多的逻辑。
您可以在实现自己的示例时使用以下示例作为参考:
#include <opencv2\opencv.hpp>
#include <vector>
#include <algorithm>
using namespace std;
using namespace cv;
void imadjust(const Mat1b& src, Mat1b& dst, int tol = 1, Vec2i in = Vec2i(0, 255), Vec2i out = Vec2i(0, 255))
{
// src : input CV_8UC1 image
// dst : output CV_8UC1 imge
// tol : tolerance, from 0 to 100.
// in : src image bounds
// out : dst image buonds
dst = src.clone();
tol = max(0, min(100, tol));
if (tol > 0)
{
// Compute in and out limits
// Histogram
vector<int> hist(256, 0);
for (int r = 0; r < src.rows; ++r) {
for (int c = 0; c < src.cols; ++c) {
hist[src(r,c)]++;
}
}
// Cumulative histogram
vector<int> cum = hist;
for (int i = 1; i < hist.size(); ++i) {
cum[i] = cum[i - 1] + hist[i];
}
// Compute bounds
int total = src.rows * src.cols;
int low_bound = total * tol / 100;
int upp_bound = total * (100-tol) / 100;
in[0] = distance(cum.begin(), lower_bound(cum.begin(), cum.end(), low_bound));
in[1] = distance(cum.begin(), lower_bound(cum.begin(), cum.end(), upp_bound));
}
// Stretching
float scale = float(out[1] - out[0]) / float(in[1] - in[0]);
for (int r = 0; r < dst.rows; ++r)
{
for (int c = 0; c < dst.cols; ++c)
{
int vs = max(src(r, c) - in[0], 0);
int vd = min(int(vs * scale + 0.5f) + out[0], out[1]);
dst(r, c) = saturate_cast<uchar>(vd);
}
}
}
int main()
{
Mat3b img = imread("path_to_image");
Mat1b gray;
cvtColor(img, gray, COLOR_RGB2GRAY);
Mat1b adjusted;
imadjust(gray, adjusted);
// int low_in, high_in, low_out, high_out
// imadjust(gray, adjusted, 0, Vec2i(low_in, high_in), Vec2i(low_out, high_out));
return 0;
}
输入图像:
输出调整后的图像:
这里有一个imadjust
和stretchlim
的实现:
你可以试着问这里的人: http : //opencv-users.1802565.n2.nabble.com/imadjust-matlab-function-with-stretchlim-OpenCV-implementation-td6253242.html
基于他的实现: http : //www.mathworks.com/matlabcentral/fileexchange/12191-bilateral-filtering
该文件应如下所示,但我不完全确定它是否有效:
void
getOptimalImgAdjustParamsFromHist (IplImage* p_img,unsigned int* p_optminmaxidx, int p_count)
{
int numBins = 256;
CvMat* bins = cvCreateMat(1,numBins,CV_8UC1);
calcHistogram(p_img,bins,numBins);
int sumlow = 0, sumhigh = 0;
int low_idx = 0, high_idx = 0;
for (unsigned int i = 0; i < numBins; i++) {
float curval = (float) cvGetReal1D (bins, (i));
sumlow += curval;
if (sumlow >= p_count) {
low_idx = i;
break;
}
}
for (unsigned int i = numBins - 1 ; i >= 0; i--) {
float curval = (float) cvGetReal1D (bins, (i));
sumhigh += curval;
if (sumhigh >= p_count) {
high_idx = i;
break;
}
}
cvReleaseMat(&bins);
p_optminmaxidx[OPTMINIDX] = low_idx;
p_optminmaxidx[OPTMAXIDX] = high_idx;
}
IplImage *
imageAdjust (IplImage * p_img)
{
CvSize framesize = cvGetSize (p_img);
int low_count = round (framesize.width * framesize.height * 0.01);
unsigned int *optminmaxidx = new unsigned int [2];
getOptimalImgAdjustParamsFromHist (p_img, optminmaxidx,low_count);
int range = optminmaxidx[OPTMAXIDX] - optminmaxidx[OPTMINIDX];
IplImage *adjustedImg = p_img;
for (int i = 0; i < framesize.height; i++)
for (int j = 0; j < framesize.width; j++) {
unsigned int val = (unsigned int) getData (p_img, i, j);
unsigned int newval = 0;
if (val <= optminmaxidx[OPTMINIDX]) {
newval = 0;
setData (adjustedImg, i, j, (uchar) newval);
} else if (val >= optminmaxidx[OPTMAXIDX]) {
newval = 255;
setData (adjustedImg, i, j, (uchar) newval);
} else {
newval =
(unsigned int) round ((double) (((double) val -
(double) optminmaxidx[OPTMINIDX]) * (double) (255.0 /
(double) range)));
setData (adjustedImg, i, j, (uchar) newval);
}
}
delete[]optminmaxidx;
return adjustedImg;
}
我希望它能帮助你。 很好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.