Opencv2实现平移、旋转、双线性差值放缩变换

来源:互联网 发布:苹果视频下载软件 编辑:程序博客网 时间:2024/06/10 01:49

1. 概述

在本文中记录集中简单的几何变换的Opencv实现,对于不是依赖Opencv实现的也可以按照类似的写法完成移植,这些函数经过测试都是可以正常使用的。

2. 实现

图像的平移变换:
//************************************************************************// 函数名称:    ImgMove// 访问权限:    public // 创建日期:2016/12/05// 创 建 人:// 函数说明:图像平移操作// 函数参数: cv::Mat & input_img输入图像// 函数参数: cv::Mat & output_img输出图像// 函数参数: const int x_diff图像X轴上的平移距离// 函数参数: const int y_diff图像Y轴上的平移距离// 返 回 值:   bool//************************************************************************bool CCalcMutualInfo::ImgMove(cv::Mat& input_img, cv::Mat& output_img, const int x_diff, const int y_diff){if (!input_img.data){cout << "asad" << endl;return false;}int Nrows(input_img.rows);int Ncols(input_img.cols);unsigned char *data1=nullptr, *data2=nullptr;cv::Mat img_temp(Nrows, Ncols, CV_8UC1, cv::Scalar::all(0));for (int i = 0; i < Nrows; i++){data2 = img_temp.ptr<uchar>(i);for (int j = 0; j < Ncols; j++){if ((i >= x_diff) && (j >= y_diff) && (i-x_diff<Nrows) && (j-y_diff<Ncols)){data1 = input_img.ptr<uchar>(i - x_diff);data2[j] = data1[j - y_diff];}else{data2[j] = 0;}}}img_temp.copyTo(output_img);return true;}
旋转变换:
//************************************************************************// 函数名称:    ImgRotate// 访问权限:    public // 创建日期:2016/12/06// 创 建 人:// 函数说明:图像旋转// 函数参数: cv::Mat & input_img输入图像// 函数参数: cv::Mat & output_img输出图像// 函数参数: const double angle图像的旋转角度// 返 回 值:   bool//************************************************************************bool CCalcMutualInfo::ImgRotate(cv::Mat& input_img, cv::Mat& output_img, const double angle){if (!input_img.data){cout << "asad" << endl;return false;}double image_high  = input_img.rows;//the width of imagedouble image_width = input_img.cols * input_img.channels();//the high of imageint Nrows = input_img.rows;//the row number of imageint Ncols = input_img.cols * input_img.channels();//the column number of imageint i=0, j=0;//loop counting uchar *data1;//the image matrix data pointeruchar *data2;cv::Mat Dst_img(input_img.rows, input_img.cols, input_img.type(), cv::Scalar::all(0));//the destination image matrix that store new imagedouble Xvar = -0.5*image_high*std::cos(angle) + 0.5*image_width*std::sin(angle) + 0.5*image_high;//the constant of X axisdouble Yvar = -0.5*image_high*std::sin(angle) - 0.5*image_width*std::cos(angle)+ 0.5*image_width;//the constant of Y axisfor (i=0; i<Nrows; i++){data1 = input_img.ptr<uchar>(i);data2 = Dst_img.ptr<uchar>(i);for (j=0; j<Ncols; j++){int X1 = static_cast<int>((double)i*std::cos(angle) - (double)j*std::sin(angle) + Xvar + 0.5);int Y1 = static_cast<int>((double)i*std::sin(angle) + (double)j*std::cos(angle) + Yvar + 0.5);if ((X1>=0) && (X1<Nrows) && (Y1>=0) && (Y1<Ncols)){data2 = Dst_img.ptr<uchar>(X1);data2[Y1] = data1[j];}}}Dst_img.copyTo(output_img);return true;}

双线性差值缩放:
//************************************************************************// 函数名称:    StretchImg// 访问权限:    public // 创建日期:2016/12/07// 创 建 人:// 函数说明:双线性差值缩放图像// 函数参数: cv::Mat & input_img输入图像// 函数参数: cv::Mat & out_img输出图像// 函数参数: double x_ratex轴放缩比例// 函数参数: double y_rateY轴放缩比例// 函数参数: int center_x图像X轴的重心图像配准使用// 函数参数: int center_y图像Y轴的重心图像配准使用// 返 回 值:   bool//************************************************************************bool CCalcMutualInfo::StretchImg(cv::Mat& input_img, cv::Mat& out_img, double x_rate, double y_rate, int center_x, int center_y){if (!input_img.data){cout << "no input img" << endl;return false;}if (0>=x_rate || 0>=y_rate){cout << "rate error" << endl;return false;}//截取重心的512*512的图像,配准用(放缩排除这几行代码)int center_x1 = (int)((double)center_x*x_rate+0.5);int center_y2 = (int)((double)center_y*y_rate+0.5);double dst_rows = input_img.rows * x_rate;//放缩之后目标图像的高度double dst_cols = input_img.cols * input_img.channels() * y_rate;//放缩之后目标图像的宽度int Nrows = input_img.rows;//原始图像的高度int Ncols = input_img.cols * input_img.channels();//原始图像的宽度double orig_x = 0, orig_y = 0;//输出图像上换算过去对应原图的点uchar *data1;//定义三个像素指针uchar *data2;uchar *data3;cv::Mat Dst_img((int)dst_rows, (int)dst_cols / input_img.channels(), input_img.type());//create a destination imageint i = 0, j = 0;//循环变量for (i = 0; i < (int)dst_rows; i++){data2 = Dst_img.ptr<uchar>(i);orig_x = static_cast<double>((double)i * (Nrows - 1) / (dst_rows - 1) + 0.5);//原图中的X坐标值for (j = 0; j < (int)dst_cols; j++){orig_y = static_cast<double>((double)j * (Ncols - 1) / (dst_cols - 1) + 0.5);//源图像的Y轴坐标double bx1 = orig_x - (int)orig_x;//计算距离系数,之后按照这个进行加权double bx2 = 1.0 - bx1;double by1 = orig_y - (int)orig_y;double by2 = 1.0 - by1;if ((orig_x >= 0) && (orig_x < Nrows) && (orig_y >= 0) && (orig_y < Ncols)){if ((orig_x < Nrows - 1) && (orig_y < Ncols - 1)){data1 = input_img.ptr<uchar>((int)orig_x);data3 = input_img.ptr<uchar>((int)orig_x + 1);data2[j] = data1[(int)orig_y] * bx2 * by2 + data1[(int)orig_y + 1] * bx2 * by1 +data3[(int)orig_y] * bx1 * by2 + data3[(int)orig_y + 1] * bx1 * by1;//计算加权之后的目标像素}}}}//截取重心的512*512的图像,配准用(放缩排除这几行代码)if (dst_rows > Nrows && dst_cols>Ncols){Dst_img = Dst_img(cv::Rect((center_x1-center_x), (center_y-center_y), 512, 512));}Dst_img.copyTo(out_img);return true;}


0 0
原创粉丝点击