matlab imadjust 用 opencv改写

来源:互联网 发布:朴槿惠犯了什么罪 知乎 编辑:程序博客网 时间:2024/05/01 20:16

原文:http://blog.csdn.net/yeyang911/article/details/18256393

自己测试的效果不是很好

实现函数功能

J = low_out +(high_out - low_out).* ((I - low_in)/(high_in - low_in)).^ gamma 


[cpp] view plain copy print?在CODE上查看代码片派生到我的代码片
  1. IplImage* ImageAdjust(IplImage *src, IplImage *dst,    
  2.           double low_in, double high_in,    
  3.           double low_out, double high_out, double gamma )    
  4. {    
  5.     double low2 = low_in*255;    
  6.     double high2 = high_in*255;    
  7.     double bottom2 = low_out*255;    
  8.     double top2 = high_out*255;    
  9.     double err_in = high2 - low2;    
  10.     double err_out = top2 - bottom2;    
  11.     
  12.     int x,y;    
  13.     double val0,val1,val2;    
  14.     
  15.     // intensity transform    
  16.     for( y = 0; y < src->height; y++) {    
  17.         for (x = 0; x < src->width; x++){    
  18.             val0 = ((uchar*)(src->imageData+src->widthStep*y))[x*src->nChannels];     
  19.             val0 = pow((val0 - low2)/err_in,gamma)*err_out+bottom2;    
  20.             if(val0>255) val0=255;     
  21.         if(val0<0) val0=0;     
  22.         ((uchar*)(dst->imageData+dst->widthStep*y))[x*src->nChannels]=(uchar)val0;    
  23.     
  24.         val1 = ((uchar*)(src->imageData+src->widthStep*y))[x*src->nChannels+1];     
  25.             val1 = pow((val1- low2)/err_in, gamma)*err_out+bottom2;    
  26.             if(val1>255) val1=255;     
  27.             if(val1<0) val1=0;    
  28.         ((uchar*)(dst->imageData+dst->widthStep*y))[x*src->nChannels+1]=(uchar)val1;    
  29.     
  30.         val2 = ((uchar*)(src->imageData + src->widthStep*y))[x*src->nChannels+2];     
  31.             val2 = pow((val2-low2)/err_in,gamma)*err_out+bottom2;    
  32.             if(val2>255) val2=255;     
  33.         if(val2<0) val2=0; // Make sure src is in the range [low,high]    
  34.         ((uchar*)(dst->imageData+dst->widthStep*y))[x*src->nChannels+2]=(uchar)val2;    
  35.         }    
  36.     }    
  37.     return 0;    
  38. }    


测试代码:

[cpp] view plain copy print?在CODE上查看代码片派生到我的代码片
  1. int main()  
  2. {  
  3.     IplImage *src=cvLoadImage("d:/111.JPG",1);  
  4.     CvSize a;  
  5.     a.width=src->width;  
  6.     a.height=src->height;  
  7.     IplImage *dst = cvCreateImage(a,8,3);  
  8.     ImageAdjust(src, dst,    
  9.           0, 0.5,    
  10.           0.5, 1, 1)  ;  
  11.     Mat c = dst;  
  12.     imshow("ss",c);  
  13.     waitKey();  
  14.     return 0;  
  15. }  
  

效果图 原图


EMGU CV 版本

[csharp] view plain copy print?在CODE上查看代码片派生到我的代码片
  1. private void imageAdjust(Image<Bgr,byte>src,Image<Bgr,byte>dst,double low_in, double high_in,  
  2.          double low_out, double high_out, double gamma)  
  3.        {  
  4.   
  5.            double low2 = low_in * 255;  
  6.            double high2 = high_in * 255;  
  7.            double bottom2 = low_out * 255;  
  8.            double top2 = high_out * 255;  
  9.            double err_in = high2 - low2;  
  10.            double err_out = top2 - bottom2;  
  11.   
  12.            int x, y;  
  13.            double val0, val1, val2;  
  14.   
  15.            // intensity transform    
  16.            for (y = 0; y < src.Height; y++)  
  17.            {  
  18.                for (x = 0; x < src.Width; x++)  
  19.                {  
  20.                     
  21.   
  22.                    val0 = src.Data[y, x, 0];  
  23.                    val0 =   Math.Pow((val0 - low2) / err_in, gamma) * err_out + bottom2;  
  24.                    if (val0 > 255) val0 = 255;  
  25.                    if (val0 < 0) val0 = 0;  
  26.                    dst.Data[y,x,0] = (byte)val0;  
  27.   
  28.   
  29.                    val1 = src.Data[y, x, 1];  
  30.                    val1 = Math.Pow((val1 - low2) / err_in, gamma) * err_out + bottom2;  
  31.                    if (val1 > 255) val1 = 255;  
  32.                    if (val1 < 0) val1 = 0;  
  33.                    dst.Data[y, x, 1] = (byte)val1;  
  34.   
  35.                    val2 = src.Data[y, x, 2];  
  36.                    val2 = Math.Pow((val2 - low2) / err_in, gamma) * err_out + bottom2;  
  37.                    if (val2 > 255) val2 = 255;  
  38.                    if (val2 < 0) val2 = 0; // Make sure src is in the range [low,high]    
  39.                    dst.Data[y, x, 2] = (byte)val2;  
  40.                }  
  41.            }  
  42.          
  43.   
  44.        }  


上面的代码对于大图运行效率低,下面我写个优化版的

代码如下:

[csharp] view plain copy print?在CODE上查看代码片派生到我的代码片
  1. private void imadjust(Image<Gray,byte> src)  
  2.        {  
  3.            double minV , maxV ;  
  4.            int [] minP = new int[2];  
  5.            int [] maxP = new int[2];  
  6.            CvInvoke.MinMaxIdx(src, out minV, out maxV, minP, maxP);  
  7.            Mat m = src.Mat;  
  8.            m.ConvertTo(m, Emgu.CV.CvEnum.DepthType.Cv32F);  
  9.            Mat n = new Mat(m.Size,Emgu.CV.CvEnum.DepthType.Cv32F,1);  
  10.            MCvScalar p = new MCvScalar();  
  11.            p.V0 = 1.0/(maxV-minV);  
  12.            n.SetTo(p);  
  13.            Mat dst = new Mat(m.Size,Emgu.CV.CvEnum.DepthType.Cv32F,1);  
  14.            CvInvoke.Multiply(m, n, dst);  
  15.            p.V0 = 255;  
  16.            n.SetTo(p);//设置矩阵为p.V0 的值  
  17.            CvInvoke.Multiply(dst, n, dst);  
  18.            pictureBox1.Image = dst.ToImage<Gray, byte>().ToBitmap();// 显示到pictureBox上  
  19.        }  

都是采用向量化(矢量化)编程方式,效率不会差,但是我是简单实现,假设输出为最小为0 最大值为255的情况,且gamma 为1时的情况

如果需要别的情形需要自己根据情况编写。

这是另一个版本,只能灰度图:

参考:http://stackoverflow.com/questions/31647274/is-there-any-function-equivalent-to-matlabs-imadjust-in-opencv-with-c

网页还有一个别的,可以测试一下

#include <opencv2/opencv.hpp>#include <vector>using namespace std;using namespace cv;/*  src and dst are grayscale, 8-bit images;  Default input value:           [low, high] = [0,1];  X-Direction           [bottom, top] = [0,1]; Y-Direction           gamma ;  if adjust successfully, return 0, otherwise, return non-zero.*/#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("fish.png");    Mat1b gray;    cvtColor(img, gray, COLOR_RGB2GRAY);    Mat1b adjusted;    imadjust(gray, adjusted);    imshow("ss",adjusted);       waitKey();    // 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;}//int main111( int argc, char** argv )//{//    IplImage *src=cvLoadImage("fish.png",1);//       CvSize a;//       a.width=src->width;//       a.height=src->height;//       IplImage *dst = cvCreateImage(a,8,3);//       ImageAdjust(src, dst,//             0, 0.5,//             0.5, 1, 1)  ;//       Mat gray_image = cvarrToMat(dst);//       imshow("ss",gray_image);//       waitKey();//    return 0;//}



0 0