基于OpenCV的循环行、列移动函数circShift()

///*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;
}

运行结果如下:

原文地址:https://www.cnblogs.com/phoenixdsg/p/8425336.html