5.8幂律变换

目录

示例代码1

运行结果1

示例代码2

运行结果2

补充示例原理

示例:使用cv::pow进行图像处理

代码

运行结果

​编辑

补充

实验代码3

运行结果3​编辑


在OpenCV中,幂律变换(Power Law Transformations)是一种常用的图像增强技术,尤其适用于调整图像的对比度。这种变换通过应用一个幂函数来调整图像的亮度,使得图像的细节更加明显。幂律变换通常用于增强图像中的暗区域或亮区域,从而提高图像的整体对比度。

OpenCV中的实现方法

虽然OpenCV并没有直接提供幂律变换的函数,但可以通过简单的数学运算来实现这一变换。具体做法是先将图像转换为浮点数类型,然后应用幂律变换,最后再将结果转换回原来的类型。

示例代码1

转换数据类型

如果原始图像的数据类型为CV_8U,可以先将其转换为CV_32F类型,然后再进行幂运算。

最后再将结果转换回CV_8U类型。// 转换为浮点数类型

cpp 复制代码
cv::Mat floatImage;
image.convertTo(floatImage, CV_32F, 1.0 / 255.0);

// 应用幂运算
cv::pow(floatImage, power, powImage);

// 将结果转换回原始类型
powImage.convertTo(powImage, CV_8U, 255.0);

下面是一个使用OpenCV实现幂律变换的示例代码:

cpp 复制代码
#include "pch.h"

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main()
{
	// 读取图像
	Mat img = imread("2.jpeg", IMREAD_COLOR);
	if (img.empty())
	{
		cerr << "无法加载图像,请检查文件路径是否正确。" << endl;
		return -1;
	}
	
	// 定义灰度矩阵
	Mat gray;
	cvtColor(img, gray, COLOR_BGR2GRAY);//转化为灰度图像

	// 定义目标矩阵
	Mat imgPowerLawTransformed;

	// 设置幂律变换的参数
	double gamma = 0.5; // 使图像变亮
	double c = 1.0;     // 常数项

	// 应用幂律变换
	//转换浮点数类型
	Mat floatImage;
	gray.convertTo(floatImage, CV_32F,1.0/255.0); // 将图像转换为32位浮点数
	pow(floatImage, gamma,imgPowerLawTransformed);      // 应用幂运算
	imgPowerLawTransformed.convertTo(imgPowerLawTransformed, CV_8U, 255.0); // 将结果转换回8位无符号整数

	// 显示原始图像和变换后的图像
	namedWindow("源图像", WINDOW_NORMAL);
	imshow("源图像", img);
	
	namedWindow("灰度图像", WINDOW_NORMAL);
	imshow("灰度图像", gray);
	
	namedWindow("幂指化后图像", WINDOW_NORMAL);
	imshow("幂指化后图像", imgPowerLawTransformed);

	waitKey(0); // 等待按键退出

	return 0;
}

代码解释
1.读取图像:使用cv::imread读取输入图像,并确保它是灰度图像。
2.获取幂次方值:可从命令行参数中读取幂次方值。
3.设置幂律变换的参数:定义幂指数 gamma 和常数 c。
4.应用幂律变换:
将图像转换为32位浮点数类型,以避免运算过程中的溢出问题。
转换为浮点数类型:将图像转换为浮点数类型CV_32F,以便进行幂运算。
应用幂律变换 s = c⋅r γ,其中 r 是图像中的像素值。
将结果转换回8位无符号整数类型,以适应图像显示的要求。
4.创建输出图像:创建一个新的cv::Mat对象来存储幂运算后的结果。
5.应用幂运算:使用cv::pow函数对图像矩阵中的每个元素进行幂运算。
6.将结果转换回原始类型:将幂运算后的结果转换回原来的类型CV_8U。
7.显示结果:使用cv::imshow函数显示原始图像和幂运算后的图像,并等待用户按键退出。

通过以上步骤,你可以使用cv::pow函数来对图像矩阵中的每个元素进行幂运算,并避免溢出问题。
总结
幂律变换是一种有效的图像增强技术,可以通过调整幂指数𝛾来增强图像的对比度。
在OpenCV中,虽然没有直接提供幂律变换的函数,
但可以通过基本的数学运算和类型转换轻松实现这一变换。
这种方法特别适用于增强图像中的暗区域或亮区域,从而提高图像的整体对比度。

运行结果1

示例代码2

示例代码2下面是一个使用cv::pow函数来计算图像矩阵中每个元素的幂的示例代码

cpp 复制代码
#include "pch.h"

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main()
{

	// 读取图像
	Mat img = imread("1.png", IMREAD_COLOR);
	if (img.empty())
	{
		cerr << "无法加载图像,请检查文件路径是否正确。" << endl;
		return -1;
	}


	// 定义灰度矩阵
	Mat gray;
	cvtColor(img, gray, COLOR_BGR2GRAY);//转化为灰度图像

	// 定义目标矩阵
	Mat imgPowerLawTransformed;

	// 设置幂律变换的参数
	double power = 2; // 使图像变亮
	//此处数值为0.5 1.5等会报错,请勘探此问题

	// 应用幂律变换
	pow(gray, power, imgPowerLawTransformed);


	// 显示原始图像和变换后的图像
	namedWindow("源图像", WINDOW_NORMAL);
	imshow("源图像", img);

	namedWindow("灰度图像", WINDOW_NORMAL);
	imshow("灰度图像", gray);


	namedWindow("幂指化后图像", WINDOW_NORMAL);
	imshow("幂指化后图像", imgPowerLawTransformed);


	waitKey(0); // 等待按键退出

	return 0;
}

//代码解释
1.读取图像:使用cv::imread读取输入图像,并确保它是灰度图像。
2.获取幂次方值:获取幂次方值。
3.创建输出图像:创建一个新的cv::Mat对象来存储幂运算后的结果。
4.应用幂运算:使用cv::pow函数对图像矩阵中的每个元素进行幂运算。
5.显示结果:使用cv::imshow函数显示原始图像和幂运算后的图像,并等待用户按键退出。

//注意事项
1.数据类型:确保输入图像的数据类型适合进行幂运算。通常情况下,灰度图像的数据类型为CV_8U(无符号8位整型)。如果需要进行浮点数运算,可以将图像转换为CV_32F或CV_64F类型。
2.溢出问题:由于原始图像的数据类型为CV_8U,在进行幂运算时可能会发生溢出。为了避免溢出,可以在进行幂运算前将图像转换为浮点数类型,然后在计算完成后将结果转换回原来的类型。

运行结果2

补充示例原理

在OpenCV中,你可以使用cv::pow函数来计算图像矩阵中每个元素的幂。这个函数可以在OpenCV的core模块中找到,用于对矩阵中的每个元素进行幂运算。

cv::pow函数的基本语法如下:

cpp 复制代码
void pow(InputArray src, double power, OutputArray dst);
参数说明:

src:输入矩阵。
power:指数值。
dst:输出矩阵,与输入矩阵具有相同的大小和类型。

使用cv::pow函数可以帮助你实现各种基于幂运算的图像处理任务,
例如对图像进行伽马校正或其他需要幂运算的图像增强技术。

示例:使用cv::pow进行图像处理

假设你想对图像进行伽马校正,这是一个常见的图像增强技术,可以通过调整图像的亮度和对比度来改善图像质量。伽马校正的基本公式是:

下面是一个使用cv::pow函数进行伽马校正的例子:

代码

cpp 复制代码
#include "pch.h"
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main() 
{
	// 读取图像
	Mat img = imread("A1.jpeg", IMREAD_GRAYSCALE);
	if (img.empty()) 
	{
		cerr << "无法加载图像,请检查文件路径是否正确。" << endl;
		return -1;
	}

	// 设置伽马值
	double gamma = 0.5; // 增加对比度
	double c = 1.0;     // 比例常数

	// 将图像转换为浮点类型
	Mat imgFloat;
	img.convertTo(imgFloat, CV_32F, c / 255.0);

	

	// 伽马校正
	Mat imgGammaCorrected;
	pow(imgFloat, gamma, imgGammaCorrected);
	imgGammaCorrected *= c * 255.0; // 调整亮度

	// 转换回8位图像
	imgGammaCorrected.convertTo(imgGammaCorrected, CV_8U);

	// 显示原始图像和伽马校正后的图像
	namedWindow("原图像", WINDOW_NORMAL);
	imshow("原图像", img);

	namedWindow("伽马校正后图像", WINDOW_NORMAL);
	imshow("伽马校正后图像", imgGammaCorrected);

	waitKey(0); // 等待按键退出

	return 0;
}



在这个示例中,我们首先将图像转换为浮点类型,
然后使用cv::pow函数对图像进行伽马校正。
注意,伽马校正后的图像需要再次转换回8位整数类型,以便于显示或保存。

如果你需要对图像进行其他基于幂运算的操作,
如对数变换等,也可以使用类似的方法。
对于对数变换,可以直接使用cv::log函数来计算自然对数,
然后再使用cv::pow来计算其他形式的幂运算。

运行结果

补充

在OpenCV中,convertTo函数是一个非常有用的函数,它可以用来执行各种类型的数值转换和缩放操作。convertTo函数可以应用于矩阵(图像),并且能够执行基本的数学运算,比如缩放、偏移等。这对于调整图像的对比度和亮度特别有用。

cpp 复制代码
convertTo函数的基本形式如下:
void convertTo(OutputArray r, int rtype, double alpha=1, double beta=0 ) const;

参数解释
dst: 目标矩阵。如果指定为None,则会自动创建一个新的矩阵。
rtype: 指定输出矩阵的数据类型(例如,cv2.CV_8U, cv2.CV_32F等)。
alpha: 缩放因子,用于调整图像的对比度。如果alpha > 1,则对比度增加;如果alpha < 1,则对比度减小。
beta: 偏移量,用于调整图像的亮度。如果beta > 0,则亮度增加;如果beta < 0,则亮度减小。
  

示例代码

cpp 复制代码
#include "pch.h"
#include <opencv2/opencv.hpp>
#include <iostream>

int main(int argc, char** argv)
{
	// 加载图像
	cv::Mat img = cv::imread("2B.png", cv::IMREAD_GRAYSCALE); // 读取为灰度图像

	if (img.empty())
	{
		std::cout << "Could not open or find the image" << std::endl;
		return -1;
	}

	// 定义变换参数
	double alpha = 1.5; // 对比度增加
	double beta = 10;   // 亮度增加

	// 创建一个空的输出图像
	cv::Mat output;

	// 使用convertTo函数调整图像
	img.convertTo(output, -1, alpha, beta);
//convertTo函数的第一个参数是输出图像,第二个参数-1表示保持输入图像的数据类型不变,第三个参数alpha是缩放因子,第四个参数beta是偏移量。

	//将输出图像转换回8位无符号整型
	//*************可需要 可不要
	//normalize(output, output, 0, 255, cv::NORM_MINMAX);//归一化,将数据归一到0-255之间;


	// 显示结果
	cv::namedWindow("Original Image", cv::WINDOW_NORMAL);
	cv::imshow("Original Image", img);

	cv::namedWindow("Transformed Image", cv::WINDOW_NORMAL);
	cv::imshow("Transformed Image", output);

	cv::waitKey(0);

	return 0;
}

运行结果

实验代码3

cpp 复制代码
#include "pch.h"
#include <iostream>
#include<opencv2/opencv.hpp>
using namespace cv;  //所有opencv类都在命名空间cv下
using namespace std;
//#pragma comment(lib, "opencv_world450d.lib")  //引用引入库 
 

int main()
{
	Mat src;
	src = imread("018.jpeg");
	if(src.empty()) //检验是否成功导入数据;
	{
		cout<<"not open successed!" <<endl;
		return -1;
	}
	//namedWindow("input",0);
	namedWindow("原图", WINDOW_NORMAL);

	imshow("原图",src); // 显示输入的图像src;
	cvtColor(src, src, COLOR_RGB2GRAY);
	Mat grayimg;
	grayimg.create(src.size(),src.type()); //创建一个大小类型相同的图像矩阵序列,也可以用clone()函数;
	int height = src.rows;
	int width = src.cols;
	for(int i=0;i<height;i++)
		for(int j=0;j<width;j++)
		{
			int gray = src.at<uchar>(i,j);
			grayimg.at<uchar>(i,j) = pow(gray, 0.5);//将灰度值开方;
		}
	normalize(grayimg,grayimg,0,255,NORM_MINMAX);//归一化,将数据归一到0-255之间;
	
	namedWindow("目标图像", WINDOW_NORMAL);
	imshow("目标图像",grayimg);//显示图像grayimg;
	waitKey(0);
	return 0;
}
 

运行结果3

相关推荐
jndingxin29 分钟前
OpenCV相机标定与3D重建(1)概述
数码相机·opencv·3d
凤枭香17 小时前
Python OpenCV 傅里叶变换
开发语言·图像处理·python·opencv
ctrey_18 小时前
2024-11-4 学习人工智能的Day21 openCV(3)
人工智能·opencv·学习
可均可可19 小时前
C++之OpenCV入门到提高004:Mat 对象的使用
c++·opencv·mat·imread·imwrite
蒙娜丽宁19 小时前
《Python OpenCV从菜鸟到高手》——零基础进阶,开启图像处理与计算机视觉的大门!
python·opencv·计算机视觉
plmm烟酒僧20 小时前
Windows下QT调用MinGW编译的OpenCV
开发语言·windows·qt·opencv
AI小杨20 小时前
【车道线检测】一、传统车道线检测:基于霍夫变换的车道线检测史诗级详细教程
人工智能·opencv·计算机视觉·霍夫变换·车道线检测
冷凝女子21 小时前
【QT】海康视频及openCv抓拍正脸接口
qt·opencv·音视频·海康
撞南墙者1 天前
OpenCV自学系列(1)——简介和GUI特征操作
人工智能·opencv·计算机视觉
柳鲲鹏1 天前
OpenCV视频防抖源码及编译脚本
人工智能·opencv·计算机视觉