Table of Contents
线性变换公式
dstImage = alpha * srcImage + beta【类比于数学中的y = ax + b】
C++代码
#include <opencv2/opencv.hpp> //头文件
#include <iostream>
using namespace cv; //包含cv命名空间
using namespace std;
int main(int argc, char ** argv)
{
Mat srcImage, dstImage;
//【1】线性变换实验
srcImage = (Mat_<uchar>(2, 2) << 0, 200, 23, 4); //创建一个2*2的数组,类型为unsigned char
//输出数组内容
cout << "src: " << endl;
for (int r = 0; r < srcImage.rows; r++)
{
for (int c = 0; c < srcImage.cols; c++){
cout << (int)srcImage.at<uchar>(r, c) << ","; //第r行c列的值
}
cout << endl;
}
//设定变量
float alpha = 2.0;
float beta = 0;
//线性变换,如下三个方法都可行,任选一个
//OpenCV对大于255的数字采取的策略是全部设定为255,即400->255, 300->255, 510->255
//method#1:
//convertTo这个函数的会对结果进行类型转换,将其转为第二个参数所指定的类型
//srcImage.convertTo(dstImage, CV_8UC1, alpha, beta);
//method#2:
//这个方法需要编程者自行转换
//dstImage = alpha * srcImage + beta;
//method#3:
//convertScaleAbs这个函数会自动转为8-bit
convertScaleAbs(srcImage, dstImage, alpha, beta);
cout << "************************ " << endl;
cout << "dst: " << endl;
for (int r = 0; r < dstImage.rows; r++)
{
for (int c = 0; c < dstImage.cols; c++){
//如果不转换为unsigned int,如果结果为空白字符,输出了会看不到,所以作此转换
cout << (unsigned int)(dstImage.at<uchar>(r, c)) << ","; //第r行c列的值
}
cout << endl;
}
// 【2】读入一张图片,并对图片进行分段线性变换
//载入图像,转为灰度图
//srcImage = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE); //从控制台传入图片参数
srcImage = imread("F:/images/img7.jpg", CV_LOAD_IMAGE_GRAYSCALE); //在程序中打开一张图片,灰度图格式
if (!srcImage.data)
{
printf("could not load image...\n");
}
char input_title[] = "input image";
char output_title[] = "output image";
namedWindow(input_title, CV_WINDOW_AUTOSIZE);
namedWindow(output_title, CV_WINDOW_AUTOSIZE);
// 显示载入的图片
imshow(input_title, srcImage);
dstImage = srcImage.clone(); //dstImage与srcImage同样尺寸,内容也一样
//对dst进行分段线性变换,遵循的公式为dstImage = alpha * srcImage + beta[即y = ax + b]
//怕被刷屏,所以此处就不输出srcImage, dstImage的像素值了
for (int r = 0; r < srcImage.rows; r++)
{
for (int c = 0; c < srcImage.cols; c++){
uchar temp = srcImage.at<uchar>(r, c);
if (temp < 50)
{
dstImage.at<uchar>(r, c) = saturate_cast<uchar>(temp * 0.5); //alpha = 0.5, beta = 0
}
else if (50 <= temp && temp < 150)
{
dstImage.at<uchar>(r, c) = saturate_cast<uchar>(temp * 3.6 - 310); //alpha = 3.6, beta = -310
}
else
{
dstImage.at<uchar>(r, c) = saturate_cast<uchar>(temp * 0.238 + 194); //alpha = 0.238, beta = 194
}
}
}
//显示效果图
imshow(output_title, dstImage);
imwrite("F:/images/img_new.jpg", dstImage); //将结果图保存起来
// 【3】等待任意按键按下
waitKey(0);
return 0;
}
程序运行结果
线性变换实验
src:
0,200,
23,4,
************************
dst:
0,255,
46,8,
对图片进行分段线性变换
左图为原图,右图为分段线性变换后的效果图。
相比较原图,更清楚些