图像处理实验1:图像灰度变换
程序员文章站
2024-03-15 08:48:11
...
要求
- 利用 OpenCV 读取图像。
具体内容:用打开 OpenCV 打开图像,并在窗口中显示 - 灰度图像二值化处理
具体内容:设置并调整阈值对图像进行二值化处理。 - 灰度图像的对数变换
具体内容:设置并调整 r 值对图像进行对数变换。 - 灰度图像的伽马变换
具体内容:设置并调整γ值对图像进行伽马变换。 - 彩色图像的补色变换
具体内容:对彩色图像进行补色变换。
过程
灰度变换
灰度变换的定义域和值域应该相等吧。
伽马变换:
对数变换:
C++的functional库
整个处理流程大致相同,只有几个变换公式不同,所以把公共部分抽象出来成为一个函数,在每个变换中调用公共处理函数。
之前打算因为几个变换的函数实现中的参数个数不同,所以打算用bind的,后来发现lambda更简洁实用些。
function基本上代替了函数指针。
虽然花费了不少时间,但算是搞懂了function、bind和lambda的区别与用法。
代码
注意:补色被我理解成反色了,代码中的这个实现错误我也懒得改了。。。
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <string>
#include <iostream>
#include <functional>
using namespace cv;
using namespace std;
void apply_LUT(Mat &src, Mat &dst, function<uchar(uchar)> pf)
{
CV_Assert(src.depth() == CV_8U);
Mat lookUpTable(1, 256, CV_8U);
uchar* p = lookUpTable.ptr();
for(int i = 0; i < 256; ++i)
p[i] = pf(i);
LUT(src, lookUpTable, dst);
imshow("image", dst);
waitKey(0);
}
void threshold_transform(Mat &src, Mat &dst, uchar thre)
{
auto fun = [=](uchar r) -> uchar {return ((r > thre) ? 1 : 0) * 255;};
apply_LUT(src, dst, fun);
}
// $s=cr^\gamma \qquad r\in[0,1]$
void gamma_transform(Mat &src, Mat &dst, float g=2, float c = 1.0)
{
auto fun = [=](uchar r) -> uchar {return (c * pow(r/255., g)*255);};
apply_LUT(src, dst, fun);
}
// $s=c\log_{v+1}(1+vr)\qquad r\in[0,1]$
void log_transform(Mat &src, Mat &dst, float v=1, float c=1)
{
auto fun = [=](uchar r) -> uchar {
return (c * 255. * log(1. + v*r/255.) / log(v + 1));};
apply_LUT(src, dst, fun);
}
void inv_transform(Mat &src, Mat &dst)
{
auto fun = [=](uchar r) -> uchar {return (255 - r);};
apply_LUT(src, dst, fun);
}
int main (int argc, char **argv)
{
String image_name((argc>1)?(argv[1]):("img_test.jpg"));
Mat image, image_gray, image_dst;
image = imread(image_name, IMREAD_COLOR);
if (image.empty()) {
cout << "Cannot read image: " << image_name << std::endl;
return -1;
}
cvtColor(image, image_gray, CV_BGR2GRAY);
namedWindow("image", CV_WINDOW_AUTOSIZE);
cout << "image origin" << endl;
imshow("image", image);
waitKey(0);
cout << "image gray" << endl;
imshow("image", image_gray);
waitKey(0);
cout << "image threshold" << endl;
// threshold(image_gray, image_dst, 128, 255, THRESH_BINARY);
threshold_transform(image_gray, image_dst, 128);
cout << "image log" << endl;
log_transform(image_gray, image_dst, 7);
cout << "image gamma" << endl;
gamma_transform(image_gray, image_dst, 9);
cout << "image inv" << endl;
inv_transform(image, image_dst);
return 0;
}
上一篇: [图像处理]图像的灰度变换