(opencv) image geometric transformation - translation

The image translation operation is to move all pixel coordinates of the image horizontally or vertically, that is, to move all pixels along the x-axis in the horizontal direction and along the y-axis in the vertical direction according to a given offset. There are two types of translation transformations: image size changing and image size invariant. The first type guarantees the complete information of the image translation, and the second type results in the possible loss of partial information of the original image. The image translation transformation formula is as follows: (I will not use the formula editor that comes with csdn, use mathtype to type it out and take a screenshot)

 For a 4*4 image matrix, translate the x-axis to the right by one unit, and translate the y-axis down by one unit. If the size of the image remains unchanged after the shift, and the excess part is filled with white, it is satisfied:

For a 4*4 image matrix, translate the x-axis to the left by one unit, and the y-axis to move up by one unit. If the size of the image is changed after the shift, the excess part will be filled with white:

 

for example: 

#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<iostream>
using namespace std;
using namespace cv;

//平移操作,图像大小不变
Mat imgTranslation1(Mat& src, int xOffset, int yOffset)
{
	int nRows = src.rows;
	int nCols = src.cols;
	Mat result (src.size(), src.type());
	//遍历图像
	for (int i = 0; i < nRows; ++i)
	{
		for (int j = 0; j < nCols; ++j)
		{
			int x = j - xOffset;
			int y = i - yOffset;
			if (x >= 0 && y >= 0 && x < nCols && y < nRows)
			{
				result.at<Vec3b>(i, j) = src.ptr<Vec3b>(y)[x];
			}
		}
	}
	return result;
}

//平移操作,图像大小改变
Mat imgTranslation2(Mat& src, int xOffset, int yOffset)
{
	//设置平移尺寸
	int nRows = src.rows + abs(yOffset);
	int nCols = src.cols + abs(xOffset);
	Mat result(nRows,nCols, src.type());
	//遍历图像
	for (int i = 0; i < nRows; ++i)
	{
		for (int j = 0; j < nCols; ++j)
		{
			//映射变换
			int x = j - xOffset;
			int y = i - yOffset;
			if (x >= 0 && y >= 0 && x < nCols && y < nRows)
			{
				result.at<Vec3b>(i, j) = src.ptr<Vec3b>(y)[x];
			}
		}
		
	}
	return result;
}
int main()
{
	Mat src = imread("C:\\Users\\32498\\Pictures\\16.png");
	if (!src.data)
	{
		return -1;
	}
	imshow("src", src);
	int xOffset = 50, yOffset = 80;
	//图像左平移不改变大小
	Mat dst1 = imgTranslation1(src, xOffset, yOffset);
	imshow("dst1", dst1);
	//图像左平移改变大小
	Mat dst2 = imgTranslation2(src, xOffset, yOffset);
	imshow("dst2", dst2);
	//图像右平移不改变大小
	Mat dst3 = imgTranslation1(src, -xOffset, -yOffset);
	imshow("dst3", dst3);
	waitKey();
	return 0;

}

The result of the operation is as follows: 

 

 Explain this line of code in the program :

result.at<Vec3b>(i, j) = src.ptr<Vec3b>(y)[x];

The pixel value at the result image (i, j) is equal to the pixel value at the y-th row and the x-th coordinate of the src image. This is actually a pixel-by-pixel operation on the image.

 ①Use of Mat data type pointer ptr in opencv

    cv::Mat image = cv::Mat(400, 600, CV_8UC1); //宽400,长600
    uchar * data00 = image.ptr<uchar>(0);
    uchar * data10 = image.ptr<uchar>(1);
    uchar * data01 = image.ptr<uchar>(0)[1];

        Notes on the above: (note the difference between these)

Define a Mat variable image,

data00 is a pointer to the first element of the first row of image

data10 is a pointer to the first element of the second row of image

data01 is a pointer to the second element of the first row of image 

②The meaning of Vec3b type

Vec3b can be regarded as vector<uchar,3>, which is a vector vector of uchar type with a length of 3. (Students who don’t know the meaning of vector container can understand vector in this way, it is an array, but the size of this array can be changed at any time, so vector is called a dynamic array)

Since the Mat image data read in opencv is stored in the uchar type of data, for the RGB three-channel image, the data of each point is a vec3b type of data.

Use the at positioning method as follows:

Mat img=imread("123.png");

//(row,col)为所需要定位点的坐标
img.at<Vec3b>(row,col)[0]=255; //修改点(row,col)的B通道数据
img.at<Vec3b>(row,col)[1]=255; //修改点(row,col)的G通道数据
img.at<Vec3b>(row,col)[2]=255; //修改点(row,col)的R通道数据


 At the same time, it should be noted that it returns the uchar type, and directly uses cout to output the character format, which needs to be converted to int type and then output:


cout<<(int)img.at<Vec3b>(row,col)[0];

Guess you like

Origin blog.csdn.net/yangSHU21/article/details/131139829