matlab imadjust 用 opencv改写

实现函数功能

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


IplImage* ImageAdjust(IplImage *src, IplImage *dst,  
          double low_in, double high_in,  
          double low_out, double high_out, double gamma )  
{  
    double low2 = low_in*255;  
    double high2 = high_in*255;  
    double bottom2 = low_out*255;  
    double top2 = high_out*255;  
    double err_in = high2 - low2;  
    double err_out = top2 - bottom2;  
  
    int x,y;  
    double val0,val1,val2;  
  
    // intensity transform  
    for( y = 0; y < src->height; y++) {  
        for (x = 0; x < src->width; x++){  
            val0 = ((uchar*)(src->imageData+src->widthStep*y))[x*src->nChannels];   
            val0 = pow((val0 - low2)/err_in,gamma)*err_out+bottom2;  
            if(val0>255) val0=255;   
        if(val0<0) val0=0;   
        ((uchar*)(dst->imageData+dst->widthStep*y))[x*src->nChannels]=(uchar)val0;  
  
        val1 = ((uchar*)(src->imageData+src->widthStep*y))[x*src->nChannels+1];   
            val1 = pow((val1- low2)/err_in, gamma)*err_out+bottom2;  
            if(val1>255) val1=255;   
            if(val1<0) val1=0;  
        ((uchar*)(dst->imageData+dst->widthStep*y))[x*src->nChannels+1]=(uchar)val1;  
  
        val2 = ((uchar*)(src->imageData + src->widthStep*y))[x*src->nChannels+2];   
            val2 = pow((val2-low2)/err_in,gamma)*err_out+bottom2;  
            if(val2>255) val2=255;   
        if(val2<0) val2=0; // Make sure src is in the range [low,high]  
        ((uchar*)(dst->imageData+dst->widthStep*y))[x*src->nChannels+2]=(uchar)val2;  
        }  
    }  
    return 0;  
}  


测试代码:

int main()
{
	IplImage *src=cvLoadImage("d:/111.JPG",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 c = dst;
	imshow("ss",c);
	waitKey();
	return 0;
}
  

效果图 原图


EMGU CV 版本

 private void imageAdjust(Image<Bgr,byte>src,Image<Bgr,byte>dst,double low_in, double high_in,
          double low_out, double high_out, double gamma)
        {

            double low2 = low_in * 255;
            double high2 = high_in * 255;
            double bottom2 = low_out * 255;
            double top2 = high_out * 255;
            double err_in = high2 - low2;
            double err_out = top2 - bottom2;

            int x, y;
            double val0, val1, val2;

            // intensity transform  
            for (y = 0; y < src.Height; y++)
            {
                for (x = 0; x < src.Width; x++)
                {
                   

                    val0 = src.Data[y, x, 0];
                    val0 =   Math.Pow((val0 - low2) / err_in, gamma) * err_out + bottom2;
                    if (val0 > 255) val0 = 255;
                    if (val0 < 0) val0 = 0;
                    dst.Data[y,x,0] = (byte)val0;


                    val1 = src.Data[y, x, 1];
                    val1 = Math.Pow((val1 - low2) / err_in, gamma) * err_out + bottom2;
                    if (val1 > 255) val1 = 255;
                    if (val1 < 0) val1 = 0;
                    dst.Data[y, x, 1] = (byte)val1;

                    val2 = src.Data[y, x, 2];
                    val2 = Math.Pow((val2 - low2) / err_in, gamma) * err_out + bottom2;
                    if (val2 > 255) val2 = 255;
                    if (val2 < 0) val2 = 0; // Make sure src is in the range [low,high]  
                    dst.Data[y, x, 2] = (byte)val2;
                }
            }
        

        }


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

代码如下:

 private void imadjust(Image<Gray,byte> src)
        {
            double minV , maxV ;
            int [] minP = new int[2];
            int [] maxP = new int[2];
            CvInvoke.MinMaxIdx(src, out minV, out maxV, minP, maxP);
            Mat m = src.Mat;
            m.ConvertTo(m, Emgu.CV.CvEnum.DepthType.Cv32F);
            Mat n = new Mat(m.Size,Emgu.CV.CvEnum.DepthType.Cv32F,1);
            MCvScalar p = new MCvScalar();
            p.V0 = 1.0/(maxV-minV);
            n.SetTo(p);
            Mat dst = new Mat(m.Size,Emgu.CV.CvEnum.DepthType.Cv32F,1);
            CvInvoke.Multiply(m, n, dst);
            p.V0 = 255;
            n.SetTo(p);//设置矩阵为p.V0 的值
            CvInvoke.Multiply(dst, n, dst);
            pictureBox1.Image = dst.ToImage<Gray, byte>().ToBitmap();// 显示到pictureBox上
        }

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

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


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值