OpenCV image in situ (without opening new space) rotate 90 degrees

Source: Internet
Author: User

A while ago a friend encountered such a problem: the image in situ clockwise rotation 90 degrees, do not open up new space. This is a seemingly simple question, and it is not easy to study and find out. After some exploration, finally found the correct algorithm, but when the use of OPENCV implementation, have encountered difficulties and have a hard time to find the problem.


First of all, to solve this problem, first simplified to 90 degrees in situ rotation of a MXN matrix A (note is not nxn phalanx). For 2x3 matrix A = {1,2,3;4,5,6}, its target is matrix B = {4,1;5,2;6,3}. Because it is in situ rotation, here A and B should point to the same size of 6 memory space.


Here is an important derivation of the formula, that is b[i][j] = A[m-1-j][i], the reader can make their own scrutiny, is the cornerstone of the later algorithm.


Okay, so if B is pointing to a new open memory, the problem is simple, as long as the space to traverse B is assigned a element by the formula above. However, for in-situ rotation is faced with a problem, give B[i][j] when assigned, the position of the original value is overwritten, how to deal with. The intuitive solution is to exchange elements, which will be exchanged between the b[i][j] and A[m-1-j][i] elements. But the new problem comes out, if you simply adopt this Exchange policy issue as follows:

Note: A and B point to the same size 6 memory space, with the first address being the same name S, then 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] (swap locations for elements 1 and 4 in memory space)


S s+5

4 2 31 5 6

B[0][1] <-> a[0][0] (element 2 in the memory space should be exchanged with the original element 1, but the position is now not 1)


So, a new strategy is needed, and if you find that the element that you are exchanging is already replaced, you need to continue to find where the element is swapped. The new algorithm core pseudo code is as follows: (reference)

For i = 0 to N-1:

For j = 0 to M-1:

///B[I][J] The elements before are correct

if (I*M+J) < ((m-1-j) *n+i)://Replace element behind B[i][j] position

swap (B[i][j], a[m-1-j][i]);

Else://To replace the element before B[i][j], has been replaced, needs to iterate to find where the element is replaced, definitely behind B[I][J]

Tar_i = m-1-j;

Tar_j = i;

While (i*m+j) > (tar_i*n+tar_j):

pos = Tar_i*n+tar_j;

tmp_i = pos/m;

Tmp_j = pos% M;

Tar_i = M-1-tmp_j;

tar_j = tmp_i;

swap (B[i][j], A[tar_i][tar_j])


The above code can achieve arbitrary matrix in situ 90 degrees clockwise rotation, the color image is only 3 channels each position by 3 elements, with the above algorithm should also be able to handle, using OpenCV wrote the following procedures:

#include <cv.h>
#include 


Test a few pictures, get a satisfactory result, one example is as follows



However, at the time of contentment, a sudden accident occurred, the individual diagram has the following effect:


This is very frustrating, the algorithm is wrong. After careful thinking, we find that there is no loophole in the algorithm. After some thought, we finally found the potential problem.


Please take a closer look at the C code above, you will find that the author assumed one thing, is that img->widthstep = Img->width * Img->nchannels, this is actually a potential hidden trouble. We usually intuitively think that image imagedata this one-dimensional array of storage is the wx3 byte of each row to store the H segment, but in fact, every row widthstep byte continuously storage h paragraph, but widthstep is not always equal to wx3, often a few more bytes. Because on a 32-bit machine, OpenCV allocates bytes in 4-byte alignment. So if the problem figure W = 706, it should have been allocated 2,118 bytes, but actually allocate 2,120 bytes (multiples of 4), 2 redundant bytes per line.


This is difficult to detect at ordinary times, but in situ rotation of the picture is highlighted in the problem, because the existence of redundant bytes, rotation before and after the OPENCV image need space may not be the same. For example, the original 700x401, image byte size is 700x401x3, and after 90 degrees 401x700, the size of the image byte to 404x700x3, indicating the origin of the space size is not enough to represent the new map.


In summary, if you really encounter the problem of 90 degrees in situ rotation of the image, two solutions:

1. Still use the opencv1.x data structure iplimge, that first resize the picture nearest to the width and height is a multiple of the value of 4.

2. Using opencv2.x data structure Cv::mat, this problem will not occur, the following is a sample program using OPENCV2.

#include <opencv2/opencv.hpp>

void swap (unsigned char& A, unsigned char& b) {
	char c = A;
	A = b;
	b = C;
}

int main () {
	cv::mat img = cv::imread ("test.jpg");
	int w = img.cols;
	int h = img.rows;
	for (int i = 0; i < w i++) 
	{for
		(int j = 0; J < H; j +) 
		{
			int i = h-1-J;
			int J = i;
			while ((I*h + j) > (I*w + j))
			{
				int p = i*w + j;
				int tmp_i = p/h;
				int tmp_j = p% h;
				I = h-1-Tmp_j;
				J = tmp_i;
			} 
			Swap (* (img.data + i*h*3 + j*3 + 0), * (Img.data + i*w*3 + j*3 + 0));
			Swap (* (img.data + i*h*3 + j*3 + 1), * (Img.data + i*w*3 + j*3 + 1));
			Swap (* (img.data + i*h*3 + j*3 + 2), * (Img.data + i*w*3 + j*3 + 2));
		}

	Img.cols = h;
	Img.rows = W;
	Img.step = h*3;

	Cv::imshow ("IMG", IMG);
	Cv::waitkey ();
	return 0;
}


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.