个人博客:http://www.chenjianqu.com/
图像基本运算?原文链接:http://www.chenjianqu.com/show-8.html
图像的点运算就是对图像中的每一个像素点进行计算,为像素点和像素点之间的运算。函数表示形式为 :B(x,y)=f[A(x,y)],其中f为映射函数。点运算有时候被称为灰度变换。
1. 线性点运算
线性点运算的函数形式可用线性方程来描述,即:
G(i,j)=T[f(i,j)]=af(i,j)+b
当a>1 时,输出图像的对比度增大;a<1时对比度减小。
当a=1,把!=0时,图像仅亮度发生变化。
当a=-1,b=255时,输出图像的灰度会反转。
以下为C++代码的实现。
Mat LinearPointOperation(Mat& src, double a, double b)
{Mat dst(src.rows, src.cols, src.type(),Scalar(0));if (src.channels() == 3) {for (int i = 0; i < src.rows; i++)for (int j = 0; j < src.cols; j++){uchar *p = src.ptr<uchar>(i, j);uchar *pdst = dst.ptr<uchar>(i, j);int ans0 = int(p[0] * a + b);int ans1 = int(p[1] * a + b);int ans2 = int(p[2] * a + b);pdst[0] = ans0 > 255 ? 255 : (ans0 >0 ? ans0 : 0);pdst[1] = ans1 > 255 ? 255 : (ans1 >0 ? ans1 : 0);pdst[2] = ans2 > 255 ? 255 : (ans2 >0 ? ans2 : 0);}}else if (src.channels() == 1){for (int i = 0; i < src.rows; i++) {uchar *srcRow = src.ptr(i);uchar *dstRow = dst.ptr(i);for (int j = 0; j < src.cols; j++){int ans0 = int(srcRow[j] * a + b);dstRow[j] = ans0 > 255 ? 255 : (ans0 > 0? ans0 : 0);}}}return dst;
}
当a=2,b=-100时,效果图如下:
当a=-1,b=255时:
2. 对数变换
s=clog(1+r)
其中,c是一个常数,,假设r≥0,根据上图中的对数函数的曲线可以看出:对数变换,将源图像中范围较窄的低灰度值映射到范围较宽的灰度区间,同时将范围较宽的高灰度值区间映射为较窄的灰度区间,从而扩展了暗像素的值,压缩了高灰度的值,能够对图像中低灰度细节进行增强。;从函数曲线也可以看出,反对数函数的曲线和对数的曲线是对称的,在应用到图像变换其结果是相反的,反对数变换的作用是压缩灰度值较低的区间,扩展高灰度值的区间。
基于OpenCV的实现,其对数变换的代码如下:
//图像的对数变换 out=c*log(1+src)/log(v) v是对数变换的底数
Mat LogOperation(Mat& src,double c,double v)
{float logArr[256];for (int i = 0; i < 256; i++) {logArr[i] = c * log(i / 255.0 + 1.0) / log(v);logArr[i] = logArr[i] > 1 ? 1 : logArr[i];}Mat dst(src.size(), CV_32FC3);for (int i = 0; i < src.rows; i++)for (int j = 0; j < src.cols; j++){uchar *p = src.ptr<uchar>(i, j);float *pdst = dst.ptr<float>(i, j);pdst[0] = logArr[p[0]];pdst[1] = logArr[p[1]];pdst[2] = logArr[p[2]];}return MatFloatToChar(dst);
}
在c=1,v=1.5的情况下:
3. 伽马变换
伽马变换又称指数变换或幂变换,公式:out=c*(src+e)^r
r>1, 较亮的区域灰度被拉伸,较暗的区域灰度被压缩的更暗,图像整体变暗;
r<1, 较亮的区域灰度被压缩,较暗的区域灰度被拉伸的较亮,图像整体变亮;
代码实现如下:
//图像的伽马变换 out=c*(src+e)^r r是伽马变换的指数,e是补偿系数
Mat GamarOperation(Mat& src, double c, double e,double r)
{Mat dst(src.size(), CV_32FC3);Mat img = MatCharToFloat(src);for (int i = 0; i < img.rows; i++)for (int j = 0; j < img.cols; j++){float *p = img.ptr<float>(i, j);float *pdst = dst.ptr<float>(i, j);float ans0 = c * pow((p[0]) + e, r);float ans1 = c * pow((p[1]) + e, r);float ans2 = c * pow((p[2]) + e, r);pdst[0] = ans0>1?1:ans0;pdst[1] = ans1>1?1:ans1;pdst[2] = ans2>1?1:ans2;}return MatFloatToChar(dst);
}
当c=1 e=0 r=0.5时效果图如下:
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态