OpenCV线性变换、分段线性变换 C++代码实例 及效果图

Table of Contents

 

线性变换公式

C++代码

程序运行结果

线性变换实验

对图片进行分段线性变换


线性变换公式

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,

对图片进行分段线性变换

左图为原图,右图为分段线性变换后的效果图。

相比较原图,更清楚些

  • 4
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值