前一阵朋友碰到这么一道题:将图像原地顺时针旋转90度,不开辟新空间。此题看似平易(题目简短),仔细研究发现着实不容易。经过一番探索后,终于找到了正确的算法,但是当使用opencv实现时,有碰到了困难而且费了一番周折才找到问题所在。
首先,解决这个问题,先简化成原地90度旋转一M×N的矩阵A(注意不是N×N方阵)。对于2×3的矩阵A = {1,2,3;4,5,6},其目标为矩阵B = {4,1;5,2;6,3}。因为是原地旋转,这里A和B应指向同一大小为6的内存空间。
这里有这样一个重要的导出公式,就是B[i][j] = A[M-1-j][i],读者可自己推敲,是后面算法的基石。
好了,这样如果B指向的是一块新开辟内存,问题就简单了,只要遍历B的空间按照上面公式取A元素赋值即可。但是,对于原地旋转就面临一个问题,给B[i][j]赋值时,该位置的原先值被覆盖,如何处理?直观的解决方案是交换元素,即将B[i][j]和A[M-1-j][i]两处元素交换。但是新问题出来了,如果简单采用此交换策略问题如下:
注意:A和B指向同一大小为6的内存空间,首地址为同一叫做S,则B[i][j] = S[i*M+j],A[i][j] = S[i*N+j]。
S S+5
1 2 3 4 5 6
B[0][0] <-> A[1][0] (内存空间中元素1和4交换位置)
S S+5
4 2 31 5 6