数字图像基本OP:OpenCV图像翻转、Resize、像素值归一化

本文详细介绍了使用OpenCV进行图像处理的三大核心操作:图像翻转、尺寸调整和像素值归一化。涵盖多种翻转方式、不同插值方法的Resize操作及四种归一化方法(L1、L2、INF、MINMAX)。通过实例代码展示了每种方法的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.图像翻转

图像翻转的本质就是像素值的映射,OpenCV提供了API flip来翻转图像,有三种翻转方式:

void flip(InputArray src, //输入
		  OutputArray dst, //输出
	      int flipCode);//旋转方式 

代码实践:

	Mat result_x, result_y, result_xy;

	//沿x轴翻转
	flip(input_image, result_x, 0);
	imshow("result_x", result_x);

	//沿y轴翻转
	flip(input_image, result_y, 1);
	imshow("result_y", result_y);

	//沿xy对角线翻转
	flip(input_image, result_xy, -1);
	imshow("result_xy", result_xy);

结果:
flip_result

2.图像Resize

图像插值是从图像低分辨率图像生成高分辨率图像的过程中插值以恢复图像中所丢失的信息,即补全图像放缩所丢失的信息。

常见的四种插值方法:

  • 近邻插值INTER_NEAREST
  • 线性插值INTER_LINEAR
  • 立方插值:INTER_CUBIC
  • 卢卡斯插值INTER_LANCZOS

OpenCV提供了resize()

void resize( InputArray src, OutputArray dst,
             Size dsize, double fx = 0, double fy = 0,
             int interpolation = INTER_LINEAR );

代码实践:

	int height = input_image.rows;
	int width = input_image.cols;
	float fx = 0.0, fy = 0.0;

	Mat result = Mat::zeros(input_image.size(), input_image.type());

	resize(input_image, result, Size(width * 2, height * 2), fx = 0, fy = 0, INTER_NEAREST);
	imshow("INTER_NEAREST", result);

	resize(input_image, result, Size(width * 2, height * 2), fx = 0, fy = 0, INTER_LINEAR);
	imshow("INTER_LINEAR", result);

	resize(input_image, result, Size(width * 2, height * 2), fx = 0, fy = 0, INTER_CUBIC);
	imshow("INTER_CUBIC", result);

	resize(input_image, result, Size(width * 2, height * 2), fx = 0, fy = 0, INTER_LANCZOS4);
	imshow("INTER_LANCZOS4", result);

3.图像像素值归一化

像素值归一化就是要把图片像素值数据经过某种算法限制在需要的一定范围内。归一化可以使没有可比性的数据变得具有可比性,同时保持相比较的数据之间的相对关系。

OpenCV提供了四种图片像素归一化的方法:

  • L1归一化 :NORM_L1
  • L2归一化 : NORM_L2
  • INF归一化 :NORM_INF
  • MINMAX归一化: NORM_MINMAX(最常用)

使用的API是normalize():

void normalize( InputArray src, //输入图片
				InputOutputArray dst, //输出图片
				double alpha = 1, //norm_type = NORM_MINMAX时下限
				double beta = 0,//norm_type = NORM_MINMAX时上限,norm_type = NORM_INF时最大值
                int norm_type = NORM_L2,
                int dtype = -1, //输出type与输入type相同
                InputArray mask = noArray()
                );

下面以20,80,100三个像素值为例解释OpenCV中四种归一化的计算方法,由于归一化后为小数,因此将20,80,100转换成浮点型20.0,80.0,100.0以减小精度丢失。

3.1 L1归一化:NORM_L1

L1归一化依据所有像素值之和,用原始像素值除以所有像素值之和即为原始像素值归一化后的值。

例如对于20.0,80.0,100.0三个像素值,它们的和为
20.0 + 80.0 + 100.0 = 200.0 20.0+80.0+100.0=200.0 20.0+80.0+100.0=200.0
20.0 / 200.0 = 0.1 20.0/200.0 = 0.1 20.0/200.0=0.1
80.0 / 200.0 = 0.4 80.0/200.0 = 0.4 80.0/200.0=0.4
100.0 / 200.0 = 0.5 100.0/200.0 = 0.5 100.0/200.0=0.5
所以20.0,80.0,100.0经过L1归一化后的值分别为0.1,0.4,0.5


3.2 L2归一化: NORM_L2

L2归一化依据于原始像素值组成的单位向量,用原始像素值除以所有原始像素值平方值之和的平方根即为原始像素值归一化后的值。

例如对于20.0,80.0,100.0三个像素值,它们的平方和为:
20.0 ∗ 20.0 + 80.0 ∗ 80.0 + 100.0 ∗ 100.0 = 16800.0 20.0*20.0+80.0*80.0+100.0*100.0=16800.0 20.020.0+80.080.0+100.0100.0=16800.0
开平方得129.61。

20.0 / 129.61 = 0.154 20.0/129.61=0.154 20.0/129.61=0.154
80.0 / 129.61 = 0.617 80.0/129.61=0.617 80.0/129.61=0.617
100.0 / 129.61 = 0.772 100.0/129.61=0.772 100.0/129.61=0.772
所以20.0,80.0,100.0经过L2归一化后的值分别为0.154,0.617,0.772


3.3 INF归一化: NORM_INF

INF归一化依据于最大值,用原始像素值除以所有原始像素值中的最大值即为原始像素值归一化后的值。

例如对于20.0,80.0,100.0三个像素值,它们的最大值为100.0,则
20.0 / 100.0 = 0.2 20.0/100.0=0.2 20.0/100.0=0.2
80.0 / 100.0 = 0.8 80.0/100.0=0.8 80.0/100.0=0.8
100.0 / 100.0 = 1.0 100.0/100.0=1.0 100.0/100.0=1.0
所以20.0,80.0,100.0经过INF归一化后的值分别为0.2,0.8,1.0


3.4 MINMAX归一化: NORM_MINMAX

INF归一化依据于最大值与最小值的差值(记为delta),用原始像素值除以所有原始像素值中的最大值即为原始像素值归一化后的值。

例如对于20.0,80.0,100.0三个像素值,它们的最小值 m i n min min20.0,最大值 m a x max max100.0,则
d e l t a = m a x − m i n = 100.0 − 20.0 = 80.0 delta=max-min=100.0-20.0=80.0 delta=maxmin=100.020.0=80.0

所以
( 20.0 − m i n ) / d e l t a = ( 20.0 − 20.0 ) / 80.0 = 0.0 (20.0-min)/delta=(20.0-20.0)/80.0=0.0 (20.0min)/delta=(20.020.0)/80.0=0.0
( 80.0 − m i n ) / d e l t a = ( 80.0 − 20.0 ) / 80.0 = 0.75 (80.0-min)/delta=(80.0-20.0)/80.0=0.75 (80.0min)/delta=(80.020.0)/80.0=0.75
( 100.0 − m i n ) / d e l t a = ( 100.0 − 20.0 ) / 80.0 = 1.0 (100.0-min)/delta=(100.0-20.0)/80.0=1.0 (100.0min)/delta=(100.020.0)/80.0=1.0
所以20.0,80.0,100.0经过MINMAX归一化后的值分别为0.0,0.75,1.0


代码实现:

	vector<double>a = {20,80,100};
	vector<double>a1(3);
	vector<double>a2(3);
	vector<double>a3(3);
	vector<double>a4(3);
	cv::normalize(a, a1, 1, 0, NORM_L1);
	cv::normalize(a, a2, 1, 0, NORM_L2);
	cv::normalize(a, a3, 1, 0, NORM_INF);
	cv::normalize(a, a4, 1, 0, NORM_MINMAX);

结果:
result

4.完整代码

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

using namespace cv;
using namespace std;

int main(int argc, char**argv)
{
	//get input image
	Mat input_image = imread("./whisper.jpg", 1);
	if (input_image.empty())
	{
		cout << "read input error!" << endl;
		return -1;
	}
	imshow("input", input_image);
#if 0
	Mat result_x, result_y, result_xy;

	//沿x轴翻转
	flip(input_image, result_x, 0);
	imshow("result_x", result_x);

	//沿y轴翻转
	flip(input_image, result_y, 1);
	imshow("result_y", result_y);

	//沿xy对角线翻转
	flip(input_image, result_xy, -1);
	imshow("result_xy", result_xy);
#endif

	int height = input_image.rows;
	int width = input_image.cols;
	float fx = 0.0, fy = 0.0;

	Mat result = Mat::zeros(input_image.size(), input_image.type());

	resize(input_image, result, Size(width * 2, height * 2), fx = 0, fy = 0, INTER_NEAREST);
	imshow("INTER_NEAREST", result);

	resize(input_image, result, Size(width * 2, height * 2), fx = 0, fy = 0, INTER_LINEAR);
	imshow("INTER_LINEAR", result);

	resize(input_image, result, Size(width * 2, height * 2), fx = 0, fy = 0, INTER_CUBIC);
	imshow("INTER_CUBIC", result);

	resize(input_image, result, Size(width * 2, height * 2), fx = 0, fy = 0, INTER_LANCZOS4);
	imshow("INTER_LANCZOS4", result);


	waitKey(0);
	destroyAllWindows();
	//system("pause");
	return 0;
}
#include<opencv2/opencv.hpp>
#include<iostream>
#include<Windows.h>

using namespace cv;
using namespace std;

int main(int argc, char**argv)
{
#if 0
	//get gray input image
	Mat gray_input_image = imread("./whisper.jpg", 0);
	if (gray_input_image.empty())
	{
		cout << "read input error!" << endl;
		return -1;
	}
	imshow("gary_input", gray_input_image);

	//转为32位浮点型
	gray_input_image.convertTo(gray_input_image, CV_32F);

	Mat result = Mat::zeros(gray_input_image.size(), CV_32FC1);
	normalize(gray_input_image, result, 1.0, 0.0, NORM_MINMAX);
	result = result * 255;
	result.convertTo(result, CV_8UC1);
	imshow("result", result);

	waitKey(0);
	destroyAllWindows();
#endif 

	vector<double>a = {20,80,100};
	vector<double>a1(3);
	vector<double>a2(3);
	vector<double>a3(3);
	vector<double>a4(3);
	cv::normalize(a, a1, 1, 0, NORM_L1);
	cv::normalize(a, a2, 1, 0, NORM_L2);
	cv::normalize(a, a3, 1, 0, NORM_INF);
	cv::normalize(a, a4, 1, 0, NORM_MINMAX);

	cout << "L1 normal:" << endl;
	for (int i = 0; i < a.size(); i++){
		cout << a1[i]<<" ";
	}
	cout << endl;

	cout << "L2 normal:" << endl;
	for (int i = 0; i < a.size(); i++){
		cout << a2[i] << " ";
	}
	cout << endl;

	cout << "INF normal:" << endl;
	for (int i = 0; i < a.size(); i++){
		cout << a3[i] << " ";
	}
	cout << endl;

	cout << "MINMAX normal:" << endl;
	for (int i = 0; i < a.size(); i++){
		cout << a4[i] << " ";
	}
	cout << endl;

	system("pause");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值