Перейти к содержимому
Compvision.ru
Include

Поворот (90,180 градусов) и отражение изображения

Recommended Posts

Начал разбираться с OpenCV. С выводом изображения с камеры в роде бы разобрался. Но ни как не могу понять как это изображение развернуть на 90 градусов. Подскажите, пожалуйста.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Начал разбираться с OpenCV. С выводом изображения с камеры в роде бы разобрался. Но ни как не могу понять как это изображение развернуть на 90 градусов. Подскажите, пожалуйста.

void cvRotateImage90( IplImage *ImIn, IplImage **ImOut) // +90 Grad

{

	int i,j,k,l,w,h,nC;

	w  = ImIn-> width;

	h  = ImIn-> height;

	nC = ImIn-> nChannels;

	*ImOut =  cvCreateImage(cvSize(h, w), IPL_DEPTH_8U, nC);

	uchar * pI = (uchar *) ImIn -> imageData;

	uchar * pO = (uchar *) (*ImOut) -> imageData;

	k = 0;

	for (i=w-1; i >= 0; i--)

	{	for (j=0; j < h; j++)

			for (l=0; l < nC; l++) 

				*(pO + k++)=*(pI + nC * w * j - nC + l + nC * i);

	}

}


void cvRotateImage_90( IplImage *ImIn, IplImage **ImOut) // -90 Grad

{

	int i,j,k,l,w,h,nC;

	w  = ImIn-> width;

	h  = ImIn-> height;

	nC = ImIn-> nChannels;

	*ImOut =  cvCreateImage(cvSize(h, w), IPL_DEPTH_8U, nC);

	uchar * pI = (uchar *) ImIn -> imageData;

	uchar * pO = (uchar *) (*ImOut) -> imageData;

	k = 0;

	for (i=0; i < w; i++)

	{	for (j=h-1; j >= 0; j--)

			for (l=0; l < nC; l++)

				*(pO + k++)=*(pI + nC * w * j - nC + l + nC * i);

	}

}

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Можно попробовать использовать функцию:

cvTranspose(const CvArr* src, CvArr* dst)

Действие ф-ции: dst(i,j) = src(j,i) .

Должна ли быть матрица (изображение) квадратной или можно работать с матрицами произвольного размера не уверен, но скорее всего размер матрицы не имеет значения.

Отражение можно получить ф-цией:

void cvFlip(const CvArr* src, CvArr* dst=NULL, int flip_mode=0)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Если картинка "вверх ногами", это случается при копировании с помощью функции cvCopy(), проще всего использовать cvFlip(image,0), где image - ваше изображение.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Если картинка "вверх ногами", это случается при копировании с помощью функции cvCopy(), проще всего использовать cvFlip(image,0), где image - ваше изображение.

Я так понял, что нужно именно РАЗВЕРНУТЬ на 90 градусов картинку, т.е.:

***************		**********

*			 *		*		* 

*			 *   =>   *		* 

*			 *		*		*

***************		*		*

					   *		*

					   **********

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Всем привет.

Пытаюсь повернуть изображение на -90. Но в результате картинку обрезает. Подскажите где косяк.

Спасибо.

IplImage* dstImg = cvCreateImage( cvSize(m_sourceImage->height, m_sourceImage->width), IPL_DEPTH_8U, 3);


		float centreX =  m_sourceImage->width/2;

		float centreY =  m_sourceImage->height/2;


		rotate(angle, centreX, centreY, m_sourceImage, dstImg );


		cvReleaseImage(&m_sourceImage);

		m_sourceImage = dstImg;
Функия rotate:
void rotate(double angle, float centreX, float centreY, IplImage* src, IplImage* dst)

{

	CvPoint2D32f centre;

	centre.x = centreX;

	centre.y = centreY;


	CvMat* translate = cvCreateMat(2, 3, CV_32FC1);


	cv2DRotationMatrix(centre, angle, 1.0, translate);


	cvWarpAffine(src, dst, translate, CV_INTER_LINEAR + CV_WARP_FILL_OUTLIERS, cvScalarAll(0));


	cvReleaseMat(&translate);

}

Input изображение:

5148652403_81745b2cf2.jpg

Output изображение:

5148679547_394c69d5b1.jpg

Целевое изображение:

5149258734_dddb569203.jpg

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Так они вроде одинаково все обрезаны :)

Не правильно выразился.

После поворота, картинка должна занимать весь размер с позиции (0,0). Но почему-то она смещена вправо и вверх (Output изображение )

Целевое изображение - я пытаюсь достичь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Не правильно выразился.

После поворота, картинка должна занимать весь размер с позиции (0,0). Но почему-то она смещена вправо и вверх (Output изображение )

Целевое изображение - я пытаюсь достичь.

А, ну все понятно, ширина стала длиной а длина шириной....

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Повернуть матрицу можно с помощью функции

void cvTransform( const CvArr* src, CvArr* dst, const CvMat* transmat,const CvMat*shiftvec=NULL )
, задав соответствующее аффинное преобразование transmat, или проще с помощью функции
CvMat* cv2DRotationMatrix(CvPoint2D32f center,double angle, double scale,CvMat* map matrix );

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Добрый день,

Не буду создавать еще одну тему.

Моя задача - повернуть картинку на +45 градусов. Проблема в том, что после поворота "обрезаются" углы исходного изображения.

Я понимаю что перед поворотом нужно вычислить размер ногово изображения. Есть можно покажите пример.

Спасибо!

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Вот здесь в конце есть пример, он содержит вращалку изображения. http://www.compvision.ru/forum/index.php?showtopic=319

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Спасибо за наводку. Но мне нужно немного другое - расчитать координаты углов нового изображения _до_ самого поворота.

А простое увеличение размера на 3 BgImage = cvCreateImage( cvSize(ImgFromFile->width*3,ImgFromFile->height*3),IPL_DEPTH_8U, ImgFromFile->nChannels ); не пойдет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Не очень понял проблему.

Есть углы (их координаты относительно центра (-w/2,-h/2),(w/2,-h/2),(-w/2,h/2),(w/2,h/2) ) поверните их на заданный угол, сместите систему координат и потом есть команда (cvBoundingRect), а можно просто найти минимумы и максимумы для x и для y координат этих точек, потом вычтите из координат всех точек координату самой левой нижней (верхней) которые будут иметь наименьшие (отрицательные) значения и все.

Матрица поворота: http://ru.wikipedia.org/wiki/%D0%9C%D0%B0%D1%82%D1%80%D0%B8%D1%86%D0%B0_%D0%BF%D0%BE%D0%B2%D0%BE%D1%80%D0%BE%D1%82%D0%B0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

пытаюсь сделать поворот изображения и вырезать внтуренний вписанный прямоугольник.

void rotate(double angle, float centreX, float centreY, IplImage* src, IplImage* dst)

{

        CvPoint2D32f centre;

        centre.x = centreX;

        centre.y = centreY;


        CvMat* warp_mat = cvCreateMat(2, 3, CV_32FC1);


        cv2DRotationMatrix(centre, angle, 1.0, warp_mat);


        cvWarpAffine(src, dst, warp_mat/*, CV_INTER_LINEAR + CV_WARP_FILL_OUTLIERS, cvScalarAll(0)*/);


        cvReleaseMat(&warp_mat);

}


//test rotate

	IplImage* src= cvLoadImage("1.PNG");

	IplImage* dst= cvCreateImage( cvGetSize(src), IPL_DEPTH_8U, 3);

	rotate(1,src->width/2,src->height/2,src,dst);

	cvSaveImage("rotate.png",dst);
пытаюсь перевести координаты (0,0) (w,0) (0,h) (w,h) через формулу
u= (m11*x + m12*y + m13)/(m31*x + m32*y + m33);

	v= (m21*x + m22*y + m23)/(m31*x + m32*y + m33);
почему то для u,v дает одинаковые значения (причем они равны u=m13,v=m23 , причем m13 отрицательное) для всех 4 точек (0,0) (w,0) (0,h) (w,h)
int m11= cvmGet(warp_mat,0,0);

		int m12= cvmGet(warp_mat,0,1);

		int m13= cvmGet(warp_mat,0,2);

		int m21= cvmGet(warp_mat,1,0);

		int m22= cvmGet(warp_mat,1,1);

		int m23= cvmGet(warp_mat,1,2);

		int m31= 0;

		int m32= 0;

		int m33= 1;

		double x=0;

		double y=0;

		double u= (m11*x + m12*y + m13)/(m31*x + m32*y + m33);

		double v= (m21*x + m22*y + m23)/(m31*x + m32*y + m33);

		x=0;

		y=h;

		u= (m11*x + m12*y + m13)/(m31*x + m32*y + m33);

		v= (m21*x + m22*y + m23)/(m31*x + m32*y + m33);

		x=w;

		y=0;

		u= (m11*x + m12*y + m13)/(m31*x + m32*y + m33);

		v= (m21*x + m22*y + m23)/(m31*x + m32*y + m33);

		x=w;

		y=h;

		u= (m11*x + m12*y + m13)/(m31*x + m32*y + m33);

		v= (m21*x + m22*y + m23)/(m31*x + m32*y + m33);

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

проблему решил прямоугольник вписанный выделяется красным.

IplImage* rotate(double angle, float centreX, float centreY, IplImage* src, bool crop)

{

	int w=src->width;

	int h=src->height;


        CvPoint2D32f centre;

        centre.x = centreX;

        centre.y = centreY;


        CvMat* warp_mat = cvCreateMat(2, 3, CV_32FC1);


        cv2DRotationMatrix(centre, angle, 1.0, warp_mat);


		double m11= cvmGet(warp_mat,0,0);

		double m12= cvmGet(warp_mat,0,1);

		double m13= cvmGet(warp_mat,0,2);

		double m21= cvmGet(warp_mat,1,0);

		double m22= cvmGet(warp_mat,1,1);

		double m23= cvmGet(warp_mat,1,2);

		double m31= 0;

		double m32= 0;

		double m33= 1;

		double x=0;

		double y=0;

		double u0= (m11*x + m12*y + m13)/(m31*x + m32*y + m33);

		double v0= (m21*x + m22*y + m23)/(m31*x + m32*y + m33);

		x=w;

		y=0;

		double u1= (m11*x + m12*y + m13)/(m31*x + m32*y + m33);

		double v1= (m21*x + m22*y + m23)/(m31*x + m32*y + m33);

		x=0;

		y=h;

		double u2= (m11*x + m12*y + m13)/(m31*x + m32*y + m33);

		double v2= (m21*x + m22*y + m23)/(m31*x + m32*y + m33);

		x=w;

		y=h;

		double u3= (m11*x + m12*y + m13)/(m31*x + m32*y + m33);

		double v3= (m21*x + m22*y + m23)/(m31*x + m32*y + m33);


		int left= MAX(MAX(u0,u2),0);

		int right= MIN(MIN(u1,u3),w);

		int top= MAX(MAX(v0,v1),0);

		int bottom= MIN(MIN(v2,v3),h);


		IplImage* dst=cvCloneImage(src);

        cvWarpAffine(src, dst, warp_mat/*, CV_INTER_LINEAR + CV_WARP_FILL_OUTLIERS, cvScalarAll(0)*/);


		if (crop)

		{

			IplImage* dst_crop= cvCreateImage(cvSize(right-left, bottom-top), IPL_DEPTH_8U, 3);

			cvSetImageROI(dst,cvRect(left,top,right-left,bottom-top));

			cvCopy(dst,dst_crop);

			cvReleaseImage(&dst);

			cvReleaseMat(&warp_mat);

			return dst_crop;

		}

		else

		{

			/*cvLine( dst, cvPoint(left,top),cvPoint(left, bottom), cvScalar(0, 0, 255, 0) ,1,CV_AA);

			cvLine( dst, cvPoint(right,top),cvPoint(right, bottom), cvScalar(0, 0, 255, 0) ,1,CV_AA);

			cvLine( dst, cvPoint(left,top),cvPoint(right, top), cvScalar(0, 0, 255, 0) ,1,CV_AA);

			cvLine( dst, cvPoint(left,bottom),cvPoint(right, bottom), cvScalar(0, 0, 255, 0) ,1,CV_AA);*/

			cvReleaseMat(&warp_mat);

			return dst;

		}

}

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

90786836.jpg

Простите, не сдержался :lol:

Только с отражением надо что-то придумать :huh:

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте учётную запись или войдите для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать учётную запись

Зарегистрируйтесь для создания учётной записи. Это просто!

Зарегистрировать учётную запись

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу

×