一.简介
图像的几何变换有距离变换 坐标映射 平移 镜像 旋转 缩放 仿射变换等
二.重映射
把一张图像重新排列像素,比如倒置
CV_EXPORTS_W void remap( InputArray src, OutputArray dst,
InputArray map1, InputArray map2,
int interpolation, int borderMode=BORDER_CONSTANT,
const Scalar& borderValue=Scalar());
#include <iostream> #include "opencv2/opencv.hpp" using namespace std; int main(int argc, char* argv[]) { cv::Mat srcImage = cv::imread("a.jpg"); if(!srcImage.data) return -1; // 输出矩阵 cv::Mat resultImage(srcImage.size(), srcImage.type()); // x与y方向矩阵 cv::Mat xMapImage(srcImage.size(), CV_32FC1); cv::Mat yMapImage(srcImage.size(), CV_32FC1); // 取图像的宽高 int rows = srcImage.rows; int cols = srcImage.cols; // 图像遍历 for( int j = 0; j < rows; j++ ) { for( int i = 0; i < cols; i++ ) { //x与y均翻转 xMapImage.at<float>(j,i) = cols - i; yMapImage.at<float>(j,i) = rows - j; } } // 重映射操作 remap(srcImage, resultImage, xMapImage, yMapImage, CV_INTER_LINEAR, cv::BORDER_CONSTANT, cv::Scalar(0,0,0)); // 输出结果 cv::imshow("srcImage", srcImage); cv::imshow("resultImage", resultImage); cv::waitKey(0); return 0; }
三.平移
图像的平移操作是将图像的所有像素坐标进行水平或垂直方向移动
//图像平移并且图像大小不变和改变 #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <iostream> // 平移操作 图像大小不变 cv::Mat imageTranslation1(cv::Mat& srcImage,int xOffset,int yOffset) { int nRows = srcImage.rows; int nCols = srcImage.cols; cv::Mat resultImage(srcImage.size(), srcImage.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) resultImage.at<cv::Vec3b>(i,j) = srcImage.ptr<cv::Vec3b>(y)[x]; } } return resultImage; } // 平移操作,图像大小改变 cv::Mat imageTranslation2(cv::Mat& srcImage, int xOffset, int yOffset) { // 设置平移尺寸 int nRows = srcImage.rows + abs(yOffset); int nCols = srcImage.cols + abs(xOffset); cv::Mat resultImage(nRows, nCols, srcImage.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) resultImage.at<cv::Vec3b>(i,j) = srcImage.ptr<cv::Vec3b>(y)[x]; } } return resultImage; } int main() { // 图像读取及判定是否正确读入 cv::Mat srcImage = cv::imread("a.jpg"); if(!srcImage.data) return -1; cv::imshow("srcImage", srcImage); int xOffset = 50, yOffset = 80; // 图像左平移不改变大小 cv::Mat resultImage1 = imageTranslation1(srcImage, xOffset, yOffset); cv::imshow("resultImage1", resultImage1); // 图像左平移改变大小 cv::Mat resultImage2 = imageTranslation2(srcImage, xOffset, yOffset); cv::imshow("resultImage2", resultImage2); //图像右平移不改变大小 xOffset = -50, yOffset = -80; cv::Mat resultImage3 = imageTranslation1(srcImage, xOffset, yOffset); cv::imshow("resultImage3", resultImage3); cv::waitKey(0); return 0; }