Opencv image scaling (enlargement, reduction), flipping, rotating

Opencv image scaling (enlargement, reduction), flipping, rotating

The most commonly used image scaling method in opencv is to use the cv2::resize() function, which requires specifying the size of the output image and the interpolation algorithm;

The most commonly used image flipping method in opencv is to use the cv::flip() function, which requires specifying the image flipping method;

The most commonly used image rotation method in opencv is to use the cv::warpAffine() function, which requires specifying the size of the output image and the interpolation algorithm;

1. Why interpolation is needed during image scaling and rotation:

By using appropriate interpolation methods, you can ensure that the image maintains reasonable visual quality and accuracy during the transformation process;

(1)Non-integer coordinate position: When performing transformations such as scaling, flipping, rotation, etc., the coordinates of the new position are usually floating point numbers. , not necessarily an integer. For example, for a 2x magnification operation, the coordinates of the pixels will become twice the original, such as 1.5, 3.7, etc. But the image can only obtain pixel values ​​at integer coordinate positions;

(2)Maintain image continuity: The interpolation algorithm can maintain the continuity and smoothness of the image during the transformation process and avoid aliasing. shaped edges or deformations;

2. Common interpolation algorithms include:
  • Nearest neighbor interpolation (cv2::INTER_NEAREST): Select the value of the pixel closest to the transformed position as the pixel value of the new position;
  • Bilinear interpolation (cv2::INTER_LINEAR): Use the weighted average of four adjacent pixels to estimate the pixel value at the new location;
  • Bicubic interpolation (cv2::INTER_CUBIC): Use the weighted average of 16 adjacent pixels to estimate the pixel value at the new location;
3. Image scaling, flipping, and rotating:
(1) Image scaling cv2::resize(), a function used to change the size of an image. It can be used for image enlargement and reduction operations:
Function prototype:
void cv::resize(
    InputArray src,
    OutputArray dst,
    Size dsize,
    double fx = 0, 
    double fy = 0,
    int interpolation = INTER_LINEAR
);

参数解释:
src:输入图像;
dst:输出图像;
dsize:输出图像的大小,通常使用cv::Size()来指定; 
fx:沿水平轴的缩放因子,如果设置为0,则通过 fy 来确定缩放比例; 
fy:沿垂直轴的缩放因子,如果设置为0,则通过 fx 来确定缩放比例; 
interpolation:插值算法(
	INTER_NEAREST
	INTER_LINEAR	默认
        INTER_CUBIC	适合放大操作
); 

Example: Reduce an image to half its original size
#include <opencv2\opencv.hpp>
#include <iostream>
#include <demo.h>

using namespace cv;
using namespace std;

int main() {
    
    
	//读取图像,BGR存储在Mat矩阵里
	Mat src = cv::imread("C:\\cpp\\image\\suzy4.jpg");
	if (src.empty()) {
    
    
		printf("could not load image..../n");
		return -1;
	}

	imshow("src", src);

	// 通过指定缩放因子,将图像缩小为原来的一半
	cv::Mat amplify1, amplify2, reduce1, reduce2;
	cv::resize(src, amplify1, cv::Size(), 0.5, 0.5, cv::INTER_LINEAR);
	cv::imshow("amplify1", amplify1);

	// 通过指定输出图像的尺寸,将图像缩小为原来的一半
	int w = src.cols;
	int h = src.rows;
	cv::resize(src, amplify2, cv::Size(w/2, h/2), 0, 0, cv::INTER_LINEAR);
	cv::imshow("amplify2", amplify2);

	// 通过指定缩放因子,将图像放大为原来的1.5倍
	cv::resize(src, reduce1, cv::Size(), 1.5, 1.5, cv::INTER_LINEAR);
	cv::imshow("reduce1", reduce1);

	// 通过指定输出图像的尺寸,将图像放大为原来的1.5倍
	cv::resize(src, reduce2, cv::Size(w*1.5, h*1.5), 0, 0, cv::INTER_LINEAR);
	cv::imshow("reduce2", reduce2);

	waitKey();
	destroyAllWindows();
	return 0;
}

(2) Image flip cv2::flip(), a function used to implement image flip (mirror) operation. It can flip horizontally, vertically, or in both directions at the same time:
Function prototype:
void cv::flip(
    InputArray src,   
    OutputArray dst,  
    int flipCode   
);

参数解释:
src:输入图像;
dst:输出图像;
flipCode:翻转方式(
	0	-> 沿x轴翻转(垂直翻转)(上下翻转)
	1	-> 沿y轴翻转(水平翻转)(左右翻转)
	-1	-> 同时沿x和y轴翻转(对角线翻转)
); 

Example: Flip an image horizontally
#include <opencv2\opencv.hpp>
#include <iostream>
#include <demo.h>

using namespace cv;
using namespace std;

int main() {
    
    
	//读取图像,BGR存储在Mat矩阵里
	Mat src = cv::imread("C:\\cpp\\image\\suzy1.jpg");
	if (src.empty()) {
    
    
		printf("could not load image..../n");
		return -1;
	}

	imshow("src", src);

	cv::Mat flipped_image;
	cv::flip(src, flipped_image, 1);    // 沿y轴翻转

	cv::imshow("Flipped Image", flipped_image);

	waitKey();
	destroyAllWindows();
	return 0;
}

(3) Image rotation cv2::warpAffine(), a function used to implement image affine transformation (image affine transformation refers to the operation of geometric transformations such as translation, rotation, scaling, and flipping of images)
Function prototype:
void cv::warpAffine(
    InputArray src, 
    OutputArray dst, 
    InputArray M, 
    Size dsize, 
    int flags = INTER_LINEAR,
    int borderMode = BORDER_CONSTANT,
    const Scalar& borderValue = Scalar()
);

1、参数解释:
src:输入图像;
dst:输出图像;
M:仿射变换矩阵,用于定义变换关系,这里定义的是旋转矩阵,需要借助cv2.getRotationMatrix2D()函数定义图像旋转参数,函数返回一个cv::Mat类型的矩阵,其中包含了进行旋转变换的矩阵信息;
dsize:输出图像的大小,通常使用cv::Size()来指定;  
flags :插值算法(
	INTER_NEAREST
	INTER_LINEAR	默认
        INTER_CUBIC	适合放大操作
); 
borderMode:边界模式,默认为BORDER_CONSTANT常数边界模式;
borderValue:borderValue默认值等于Scalar(),表示创建一个所有通道值为0的常量颜色,

2、定义旋转矩阵:
cv::Mat cv::getRotationMatrix2D(
	cv::Point2f center, 	// 旋转的中心坐标 (x, y),类型为cv::Point2f,使用的是浮点数作为坐标
	double angle, 		// 旋转角度,以度为单位(正值表示逆时针旋转,负值表示顺时针旋转)
	double scale		// 缩放比例,可选参数,默认为1.0
);

3、注意:
const Scalar& borderValue = Scalar()表达式的含义如下:
Scalar 是OpenCV库中用于表示多通道颜色值的数据类型,可以包括1到4个通道;
borderValue 是函数的参数名,它表示用于边界填充的颜色值;
=Scalar() 表示给定参数的默认值,在这里Scalar()创建了一个所有通道值为0的标量(黑色),用于作为默认的边界填充颜色;
const修饰符,表示borderValue是一个常量引用,即在函数中不能对其进行修改;

Example: Rotate an image according to a specified angle
#include <opencv2\opencv.hpp>
#include <iostream>
#include <demo.h>

using namespace cv;
using namespace std;

int main() {
    
    
	//读取图像,BGR存储在Mat矩阵里
	Mat src = cv::imread("C:\\cpp\\image\\suzy1.jpg");
	if (src.empty()) {
    
    
		printf("could not load image..../n");
		return -1;
	}
	//namedWindow("src", WINDOW_NORMAL);
	imshow("src", src);

	cv::Mat rotated_image;
	// 图像src的中心点坐标
	cv::Point2f center(src.cols/2.0, src.rows/2.0);
	// 定义一个角度
	double angle = 45.0;
	// 定义了一个旋转矩阵
	cv::Mat rotation_matrix = cv::getRotationMatrix2D(center, angle, 1.0);
	// 将图像按照定义的rotation_matrix旋转变换的矩阵信息,进行旋转
	cv::warpAffine( src, rotated_image, rotation_matrix, src.size(), INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 255) );

	cv::imshow("Rotated Image", rotated_image);

	waitKey();
	destroyAllWindows();
	return 0;
}

In the above example, the rotated image cannot be guaranteed to be completely visible. It is also necessary to calculate the width and height of the rotated image, as well as the coordinates of the center point after rotation.
#include <opencv2\opencv.hpp>
#include <iostream>
#include <demo.h>

using namespace cv;
using namespace std;

int main() {
    
    
	//读取图像,BGR存储在Mat矩阵里
	Mat src = cv::imread("C:\\cpp\\image\\suzy1.jpg");
	if (src.empty()) {
    
    
		printf("could not load image..../n");
		return -1;
	}
	//namedWindow("src", WINDOW_NORMAL);
	imshow("src", src);

	cv::Mat dst;
	int w = src.cols;
	int h = src.rows;
	// 图像src的中心点坐标
	cv::Point2f center(w/2.0, h/2.0);
	// 定义一个角度
	double angle = 45.0;
	// 定义了一个旋转矩阵
	cv::Mat M = cv::getRotationMatrix2D(center, angle, 1.0);
	// 下几行代码用于调整旋转后图像的位置,确保旋转后图像完全可见
	double cos = abs(M.at<double>(0, 0));
	double sin = abs(M.at<double>(0, 1)); 
	// 旋转后图像的宽度nw和高度nh
	int nw = int( abs(cos)*w + abs(sin)*h );
	int nh = int( abs(sin)*w + abs(cos)*h );
	// 旋转后图像的中心点位置
	M.at<double>(0, 2) += (nw/2 - w/2);
	M.at<double>(1, 2) += (nh/2 - h/2);
	// 由于计算出的 nw 和 nh 可能是浮点数,但 cv::warpAffine()函数的第四个参数(目标图像的大小)需要整数类型
	cv::Size newSize(nw, nh);
	// 将图像按照定义的rotation_matrix旋转变换的矩阵信息,进行旋转
	cv::warpAffine( src, dst, M, newSize, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 255, 255) );

	cv::imshow("Rotated Image", dst);

	waitKey();
	destroyAllWindows();
	return 0;
}

Guess you like

Origin blog.csdn.net/qq_33867131/article/details/133086843