实现函数功能
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;
- }
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;
- }
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 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上
- }
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时的情况
如果需要别的情形需要自己根据情况编写。
实现函数功能
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;
- }
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;
- }
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 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上
- }
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时的情况
如果需要别的情形需要自己根据情况编写。