///*12 在Matlab中有个circShift()函数,可以实现行、列的循环移动
/// 在返卷积运算中,会用到这个函数。所以,在Opencv中我也定义同样
/// 功能的函数
/// 该函数有3个参数,第1个src是输入矩阵或图像,第2、3个参数分别是
/// 沿着'行'方向移动的函数,和沿着‘列’方向移动的列数。
在主函数circShift()中分别调用了两个子涵数:
circRowShift(Mat&src,int shift_m_rows)、
void circColShift(Mat& src,int shift_n_cols)
这两个函数分别实现了行循环移动和列循环移动,函数代码如下:
//*11.循环行、列移动函数circshift(): inline void circRowShift(Mat&src,int shift_m_rows) { int m=shift_m_rows; int rows=src.rows; //‘行’循环移动 if(m%rows==0) { return; } Mat mrows(abs(m),src.cols,src.type());//用于暂时保存末尾的m行数据 if(m>0) { src(Range(rows-m,rows),Range::all()).copyTo(mrows); src(Range(0,rows-m),Range::all()).copyTo(src(Range(m,rows),Range::all())); mrows.copyTo(src(Range(0,m),Range::all())); }else { src(Range(0,-m),Range::all()).copyTo(mrows); src(Range(-m,rows),Range::all()).copyTo(src(Range(0,rows+m),Range::all())); mrows.copyTo(src(Range(rows+m,rows),Range::all())); } } inline void circColShift(Mat& src,int shift_n_cols) { int n=shift_n_cols; int cols=src.cols; int rows=src.rows; if(n%cols==0) { return; } ///ncols,如果n>0,用于暂时保存末尾的n列数据 ///ncols,如果n<0,用于暂时保存起始的n列数据 Mat ncols(rows,abs(n),src.type()); if(n>0) { src(Range::all(),Range(cols-n,cols)).copyTo(ncols); src(Range::all(),Range(0,cols-n)).copyTo(src(Range::all(),Range(n,cols))); ncols.copyTo(src(Range::all(),Range(0,n))); } else { src(Range::all(),Range(0,-n)).copyTo(ncols); src(Range::all(),Range(-n,cols)).copyTo(src(Range::all(),Range(0,cols+n))); ncols.copyTo(src(Range::all(),Range(cols+n,cols))); } } void circShift(Mat&src,int shift_m_rows,int shift_n_cols) { int m=shift_m_rows; int n=shift_n_cols; //‘行’循环移动 circRowShift(src,m); //‘列’循环移动 circColShift(src,n); } //*11.行、列循环移动函数circshift() 结束
测试程序,对imgc移动3列:
int main() { // Mat img1=imread("D:/CodeWork/MyImage/baboon.jpg",0); Mat imgc=(Mat_<uchar>(9,12) <<0,1,2,3,4,5,6,7,8,9,10,11, 0,1,2,3,4,5,6,7,8,9,10,11, 0,1,2,3,4,5,6,7,8,9,10,11, 0,1,2,3,4,5,6,7,8,9,10,11, 0,1,2,3,4,5,6,7,8,9,10,11, 0,1,2,3,4,5,6,7,8,9,10,11, 0,1,2,3,4,5,6,7,8,9,10,11, 0,1,2,3,4,5,6,7,8,9,10,11, 0,1,2,3,4,5,6,7,8,9,10,11); Mat imgr=imgc.t(); cout<<"original imgc="<<endl<<imgc<<endl; circShift(imgc,0,3); // circShift(imgc,0,3); cout<<"3 cols-shifted imgc="<<endl<<imgc<<endl; waitKey(); return 0; }
运行结果如下:
测试程序,对imgr移动3行:
int main() { // Mat img1=imread("D:/CodeWork/MyImage/baboon.jpg",0); Mat imgc=(Mat_<uchar>(9,12) <<0,1,2,3,4,5,6,7,8,9,10,11, 0,1,2,3,4,5,6,7,8,9,10,11, 0,1,2,3,4,5,6,7,8,9,10,11, 0,1,2,3,4,5,6,7,8,9,10,11, 0,1,2,3,4,5,6,7,8,9,10,11, 0,1,2,3,4,5,6,7,8,9,10,11, 0,1,2,3,4,5,6,7,8,9,10,11, 0,1,2,3,4,5,6,7,8,9,10,11, 0,1,2,3,4,5,6,7,8,9,10,11); Mat imgr=imgc.t(); cout<<"original imgr="<<endl<<imgr<<endl; circShift(imgr,0,3); cout<<"3 rows-shifted imgr="<<endl<<imgr<<endl; waitKey(); return 0; }
运行结果如下: