matlab移位操作函数之circshift + fftshift + ifftshift

本文详细介绍了循环移位函数circshift在MATLAB中的用法,包括沿不同维度的移位操作,并通过实例演示了如何实现图像的翻转。此外,还探讨了fftshift和ifftshift在傅里叶变换中的作用,用于将零频率成分移动到频谱中心。最后,提供了一个C++实现循环移位操作的示例代码,适用于单通道矩阵。
摘要由CSDN通过智能技术生成

循环移位函数circshift

circshift Shift positions of elements circularly.
Y = circshift(X,K) where K is an integer scalar circularly shifts
the elements in the array X by K positions along the first dimension.
If K is positive, the values of X are shifted down in row direction or shifted right in col direction.
If it is negative, the values of X are shifted up in row direction or shifted left in col direction.

  • 注: 移位参数K的正负方向与图像坐标系的方向相同,大于0表示沿x轴向右或沿y轴下移,小于0表示沿x轴向左或沿y轴上移

matlab举例说明

Y = circshift(X,K,DIM) circularly shifts along the dimension DIM.
 
Y = circshift(X,V) circularly shifts the values in the array X
by V elements. V is a vector of integers where the N-th element 
specifies the shift amount along the N-th dimension of
array X. 
 
Examples:
   A = [ 1 2 3;4 5 6; 7 8 9];
   % circularly shifts first dimension values down by 1.
   B = circshift(A,1) % 沿y轴向下移一位
   B =     7     8     9
           1     2     3
           4     5     6
   % 沿行向下移一位之后,再向左移一位
   B = circshift(A,[1 -1]) % circularly shifts first dimension values
                           % down by 1 and second dimension left by 1.
   B =     8     9     7
           2     3     1
           5     6     4
 
沿x或y轴翻转 类似cv2.filp()操作
A = [ 1 2 3; 4 5 6; 7 8 9];
B = A(:,end:-1:1) %沿垂直方向Y轴翻转
% B = A(end:-1:1, :) %沿水平方向X轴翻转
C = circshift(B,[0,1]) %翻转之后再进行列移位,右移1位
B = 
     3     2     1
     6     5     4
     9     8     7
C = 
     1     3     2
     4     6     5
     7     9     8

fftshift + ifftshift

>> help fftshift
 fftshift Shift zero-frequency component to center of spectrum.
 将频率在0附近的成分移到频谱的中心
    For vectors, fftshift(X) swaps the left and right halves of
    X.  For matrices, fftshift(X) swaps the first and third
    quadrants and the second and fourth quadrants.  For N-D
    arrays, fftshift(X) swaps "half-spaces" of X along each
    dimension.
 
    fftshift(X,DIM) applies the fftshift operation along the 
    dimension DIM.
 
    fftshift is useful for visualizing the Fourier transform with
    the zero-frequency component in the middle of the spectrum.
 
    Class support for input X:
       float: double, single
 
    See also ifftshift, fft, fft2, fftn, circshift.


>> help ifftshift %% ifftshift undoes the effects of FFTSHIFT.对傅里叶变换平移的撤销
 ifftshift Inverse FFT shift.
    For vectors, ifftshift(X) swaps the left and right halves of
    X.  For matrices, ifftshift(X) swaps the first and third
    quadrants and the second and fourth quadrants.  For N-D
    arrays, ifftshift(X) swaps "half-spaces" of X along each
    dimension.
 
    ifftshift(X,DIM) applies the ifftshift operation along the 
    dimension DIM.
 
    Class support for input X: 
       float: double, single
 
    See also fftshift, fft, fft2, fftn, circshift.

    ifftshift will undo the results of fftshift. If the matrix X contains an odd number of elements, ifftshift(fftshift(X)) must be done to obtain the original X. Simply performing fftshift(X) twice will not produce X.
    
  • 傅里叶变换平移函数fftshift的本质是当移位的大小为输入矩阵行列的1/2时,循环移位的操作;即将输入矩阵分为四个象限,第1和3象限互换,第2和4象限互换,如下图所示在这里插入图片描述
  • 逆傅里叶变换平移函数ifftshift是fftshift操作的逆向还原操作;
  • 注意的是:当输入矩阵的行列为奇数时,调用circshift函数时,将输入参数除以2,向下取整后等价于fftshift操作;向上取整等价于ifftshift操作
	//execute the fftshift operation
	int xShift = (int)(input.cols / 2.0);
	int yShift = (int)(input.rows / 2.0);

	cv::Mat fftshift;
	CircShiftFunc(input, fftshift, xShift, yShift);
	
    //execute the ifftshift operation
	cv::Mat ifftMat;
	int xShift1 = (int)ceil(fftshift.cols / 2.0);
	int yShift1 = (int)ceil(fftshift.rows / 2.0);
	CircShiftFunc(fftshift, ifftMat, xShift1, yShift1);
  • c++实现循环移位操作,借助opencv,基于单通道矩阵
#include <string>
#include <iostream>
#include<string.h>
#include <vector>
#include <opencv2/opencv.hpp>
using namespace std;
//only for single channels mat , similar to circshift function in matlab
void CircShiftFunc(const cv::Mat& src, cv::Mat& dst, int xShift, int yShift) {
	dst = cv::Mat::zeros(src.size(), src.type());
	int w = src.cols;
	int h = src.rows;
	
	int sstep = src.step;
	int dstep = dst.step;
	sstep /= src.elemSize(); //num of element of each row
	dstep /= dst.elemSize();
	
	int* indexCol = (int*)malloc(sizeof(*indexCol)*w);

	//get mod number
	xShift = (w + xShift % w) % w;
	yShift = (h + yShift % h) % h;

	for (int j = 0; j < w; ++j)
	{
		indexCol[j] = (w + j - xShift) % w;
	}
	//CV_8UC1
	if (src.type() == 0) {
		const uchar* sptr = src.data;
		uchar* dptr = dst.data;
		for (int i = 0; i < h; ++i)
		{
			int ii = (h + i - yShift) % h;
			const uchar* ptmp = sptr + sstep*ii;
			for (int j = 0; j < w; ++j)
			{
				dptr[j] = ptmp[indexCol[j]];
			}
			dptr += dstep;
		}
	}
	//CV_32FC1
	else if (src.type() == 5) {
		const float* sptr =(float*)src.data;
		float* dptr = (float*)dst.data;
		for (int i = 0; i < h; ++i)
		{
			int ii = (h + i - yShift) % h;
			const float* ptmp = sptr + sstep*ii;
			for (int j = 0; j < w; ++j)
			{
				dptr[j] = ptmp[indexCol[j]];
			}
			dptr += dstep;
		}
	}

	free(indexCol);
	indexCol = NULL;
}


int main() {
	cv::Mat temp = cv::Mat::zeros(cv::Size(3, 4), CV_8UC1);
	for (int i = 0; i < temp.rows; i++) {
		for (int j = 0; j < temp.cols; j++) {
			temp.at<uchar>(i, j) = i * temp.cols + j + 1;
			printf("%d ", temp.at<uchar>(i, j));
		}
		printf("\n");
	}
	printf("*********\n");

	int xShift = (int)ceil(temp.cols / 2.0);
	int yShift = (int)ceil(temp.rows / 2.0);
	printf("%d, %d\n", xShift, yShift);

	cv::Mat rightDown;
	CircShiftFunc(temp, rightDown, xShift, yShift); //循环移位,右移和下移1位

	for (int i = 0; i < rightDown.rows; i++) {
		for (int j = 0; j < rightDown.cols; j++) {
			printf("%d ", rightDown.at<uchar>(i, j));
		}
		printf("\n");
	}
	return 0;
}
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值