coding rotation any angle

Suggestions for MicroDicom viewer
Post Reply
cutun
Posts: 1
Joined: Thu Oct 15, 2009 10:05 am

coding rotation any angle

Post by cutun » Thu Oct 15, 2009 10:16 am

As I see you based on opencv. So I post my code (i use ipl but all the function is same in opencv)

Code: Select all

// IPLImage.cpp: implementation of the CIPLImage class.
//
//////////////////////////////////////////////////////////////////////

#include "../stdafx.h"
//#include "../Vceph2.h"
#include "IPLImage.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

#include "math.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CIPLImage::CIPLImage()
{
	m_pIPLImage = NULL;
}

CIPLImage::~CIPLImage()
{
	Free();
}

bool CIPLImage::Create(int width, int height, int depth)
{
	if(m_pIPLImage)
		Free();

	if (depth == 8)
	{
		m_pIPLImage = iplCreateImageHeader(1,0,IPL_DEPTH_8U, "Gray", "GRAY", IPL_DATA_ORDER_PIXEL, 
			IPL_ORIGIN_BL, IPL_ALIGN_DWORD,width, height, NULL, NULL,NULL, NULL);
	}
	else // if (depth == 24)
	{
		m_pIPLImage = iplCreateImageHeader(3,0,IPL_DEPTH_8U,"RGB", "RGB", IPL_DATA_ORDER_PIXEL, 
			IPL_ORIGIN_BL, IPL_ALIGN_DWORD,width, height, NULL, NULL,NULL, NULL);
	}

	iplAllocateImage( m_pIPLImage, 1, 255 );
	if( NULL == m_pIPLImage->imageData ) return false;

	return true;
}

void CIPLImage::Free()
{
	if(m_pIPLImage)
		iplDeallocate( m_pIPLImage, IPL_IMAGE_ALL);
}

bool CIPLImage::OpenWithDIB(BITMAPINFOHEADER* bmphdr)
{
	/*
	if( bmphdr ) m_pIPLImage = iplTranslateDIB( bmphdr, &m_clone );
	if(m_pIPLImage==NULL) return FALSE;

	return true;
	*/

	if(m_pIPLImage)
		iplDeallocate( m_pIPLImage, IPL_IMAGE_ALL);
	
	if (bmphdr->biBitCount == 8)
	{
		m_pIPLImage = iplCreateImageHeader(1, 0, IPL_DEPTH_8U, "GRAY", "GRAY", IPL_DATA_ORDER_PIXEL, 
			IPL_ORIGIN_BL, IPL_ALIGN_DWORD, bmphdr->biWidth, bmphdr->biHeight, NULL, NULL, NULL, NULL);
	}
	else //if (depth == 24)
	{
		m_pIPLImage = iplCreateImageHeader(3, 0, IPL_DEPTH_8U, "RGB", "BGR", IPL_DATA_ORDER_PIXEL, 
			IPL_ORIGIN_BL, IPL_ALIGN_DWORD, bmphdr->biWidth, bmphdr->biHeight, NULL, NULL, NULL, NULL);
	}
	
	iplConvertFromDIB( bmphdr, m_pIPLImage );
	
	if(m_pIPLImage==NULL) return FALSE; 
	
	return true;
}

BITMAPINFO* CIPLImage::GetbmpInfo()
{
	bool isrgb =
		'R' == toupper( m_pIPLImage->colorModel[0] ) && 
		'G' == toupper( m_pIPLImage->colorModel[1] ) && 
		'B' == toupper( m_pIPLImage->colorModel[2] );
	
	bool isgray = 'G' == toupper( m_pIPLImage->colorModel[0] );
	
	if( !isgray && !isrgb ) return false;
	if( (1 == m_pIPLImage->nChannels) != isgray ) return false;
	
	char buf[ sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*256 ];
	BITMAPINFOHEADER* dibhdr = (BITMAPINFOHEADER*)buf;
	COLORREF* rgb = (COLORREF*)( buf + sizeof(BITMAPINFOHEADER) );
	
	if( isgray ) for( int i = 0; i < 256; i++) rgb[i] = RGB( i,i,i );
	
	dibhdr->biSize = sizeof( BITMAPINFOHEADER );
	dibhdr->biWidth = m_pIPLImage->width;
	dibhdr->biHeight = m_pIPLImage->height;
	dibhdr->biPlanes = 1;
	dibhdr->biBitCount = (WORD)(8 * m_pIPLImage->nChannels);
	dibhdr->biCompression = BI_RGB;
	dibhdr->biSizeImage = m_pIPLImage->imageSize;
	dibhdr->biXPelsPerMeter = 0;
	dibhdr->biYPelsPerMeter = 0;
	dibhdr->biClrUsed = 0;
	dibhdr->biClrImportant = 0; 

	return (BITMAPINFO*)dibhdr;
}

bool CIPLImage::Draw(HDC hDC, LPRECT lpDCRect)
{
	bool isrgb =
		'R' == toupper( m_pIPLImage->colorModel[0] ) && 
		'G' == toupper( m_pIPLImage->colorModel[1] ) && 
		'B' == toupper( m_pIPLImage->colorModel[2] );
	
	bool isgray = 'G' == toupper( m_pIPLImage->colorModel[0] );
	
	if( !isgray && !isrgb ) return false;
	if( (1 == m_pIPLImage->nChannels) != isgray ) return false;
	
	char buf[ sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*256 ];
	BITMAPINFOHEADER* dibhdr = (BITMAPINFOHEADER*)buf;
	COLORREF* rgb = (COLORREF*)( buf + sizeof(BITMAPINFOHEADER) );
	
	if( isgray ) for( int i = 0; i < 256; i++) rgb[i] = RGB( i,i,i );
	
	dibhdr->biSize = sizeof( BITMAPINFOHEADER );
	dibhdr->biWidth = m_pIPLImage->width;
	dibhdr->biHeight = m_pIPLImage->height;
	dibhdr->biPlanes = 1;
	dibhdr->biBitCount = (WORD)(8 * m_pIPLImage->nChannels);
	dibhdr->biCompression = BI_RGB;
	dibhdr->biSizeImage = m_pIPLImage->imageSize;
	dibhdr->biXPelsPerMeter = 0;
	dibhdr->biYPelsPerMeter = 0;
	dibhdr->biClrUsed = 0;
	dibhdr->biClrImportant = 0; 
	
	::SetDIBitsToDevice( 
			hDC,					// handle to DC
			lpDCRect->left,			// x-coord of destination upper-left corner
			lpDCRect->top,			// y-coord of destination upper-left corner 			
			m_pIPLImage->width,		// source rectangle width
			m_pIPLImage->height,	// source rectangle height
			0,						// x-coord of source lower-left corner
			0,						// y-coord of source lower-left corner
			0,						// first scan line in array			
			m_pIPLImage->height,	// number of scan lines
			m_pIPLImage->imageData, // array of DIB bits
			(BITMAPINFO*)dibhdr,	// bitmap information
			DIB_RGB_COLORS			// RGB or palette indexes
			);
	
	return true;
}

bool CIPLImage::SetROI(int xOffset, int yOffset, int width, int height)
{
	if (xOffset < 0 || yOffset < 0 || xOffset + width > GetWidth() || yOffset + height > GetHeight())
		return false;

	IplROI* roi = iplCreateROI(0, xOffset, yOffset, width, height);
	
	if (m_pIPLImage->roi)
	{
		iplDeleteROI(m_pIPLImage->roi);
	}
	
	m_pIPLImage->roi = roi;

	return TRUE;
}

/******************************************************
				Image Orientation 
******************************************************/
void CIPLImage::InvertRL()	//flip vertically
{
	iplMirror(m_pIPLImage, m_pIPLImage, 1);
}

void CIPLImage::InvertHF()	//flip horizontally
{
	iplMirror(m_pIPLImage, m_pIPLImage, 0);
}

BOOL CIPLImage::RotateRight()
{
	int width = GetWidth();
	int height = GetHeight();
		
	IplImage* pIPLImage = iplCloneImage(m_pIPLImage);

	if (m_pIPLImage)
		iplDeallocateImage(m_pIPLImage);

	m_pIPLImage = iplCreateImageHeader(3, 0, IPL_DEPTH_8U, "RGB", "BGR", IPL_DATA_ORDER_PIXEL,
		IPL_ORIGIN_BL, IPL_ALIGN_DWORD, height, width, NULL, NULL, NULL, NULL);

	iplAllocateImage( m_pIPLImage, 1, 255 );
	
	const double affine_coeff[2][3] = {0, 1, 0, -1, 0, width};

	IplROI* roi = iplCreateROI(0, pIPLImage->roi->yOffset, width - pIPLImage->roi->xOffset - pIPLImage->roi->width, pIPLImage->roi->height, pIPLImage->roi->width);

	IplROI* roi2 = iplCreateROI(0, 0, 0, pIPLImage->width, pIPLImage->height);
	IplROI* roi3 = iplCreateROI(0, 0, 0, pIPLImage->height, pIPLImage->width);

	if (pIPLImage->roi)
	{
		iplDeleteROI(pIPLImage->roi);
	}
	if (m_pIPLImage->roi)
	{
		iplDeleteROI(m_pIPLImage->roi);
	}
	
	pIPLImage->roi = roi2;
	m_pIPLImage->roi = roi3;
	
	iplWarpAffine(pIPLImage, m_pIPLImage, affine_coeff, IPL_INTER_LINEAR);
	
	if (m_pIPLImage->roi)
	{
		iplDeleteROI(m_pIPLImage->roi);
	}
	
	m_pIPLImage->roi = roi;

	//Delete pIPLImage
	iplDeallocate( pIPLImage, IPL_IMAGE_ALL );

	if (iplGetErrStatus() != IPL_StsOk ) 
		return 0;
	else
		return 1;
}

BOOL CIPLImage::RotateLeft()
{
	int width = GetWidth();
	int height = GetHeight();
		
	IplImage* pIPLImage = iplCloneImage(m_pIPLImage);

	if (m_pIPLImage)
		iplDeallocateImage(m_pIPLImage);

	m_pIPLImage = iplCreateImageHeader(3, 0, IPL_DEPTH_8U, "RGB", "BGR", IPL_DATA_ORDER_PIXEL,
		IPL_ORIGIN_BL, IPL_ALIGN_DWORD, height, width, NULL, NULL, NULL, NULL);

	iplAllocateImage( m_pIPLImage, 1, 255 );
	
	const double affine_coeff[2][3] = {0, -1, height, 1, 0, 0};

	IplROI* roi = iplCreateROI(0, height - pIPLImage->roi->yOffset - pIPLImage->roi->height, pIPLImage->roi->xOffset, pIPLImage->roi->height, pIPLImage->roi->width);

	IplROI* roi2 = iplCreateROI(0, 0, 0, pIPLImage->width, pIPLImage->height);
	IplROI* roi3 = iplCreateROI(0, 0, 0, pIPLImage->height, pIPLImage->width);

	if (pIPLImage->roi)
	{
		iplDeleteROI(pIPLImage->roi);
	}
	if (m_pIPLImage->roi)
	{
		iplDeleteROI(m_pIPLImage->roi);
	}
	
	pIPLImage->roi = roi2;
	m_pIPLImage->roi = roi3;

	iplWarpAffine(pIPLImage, m_pIPLImage, affine_coeff, IPL_INTER_LINEAR);

	if (m_pIPLImage->roi)
	{
		iplDeleteROI(m_pIPLImage->roi);
	}
	
	m_pIPLImage->roi = roi;

	//Delete pIPLImage
	iplDeallocate( pIPLImage, IPL_IMAGE_ALL );
    
	if (iplGetErrStatus() != IPL_StsOk )
		return 0;
	else
		return 1;
}

BOOL CIPLImage::RotateAngle(double rotate_rad)
{
	int width = GetWidth();
	int height = GetHeight();
	int width_new, height_new;
	double _cos = cos(rotate_rad);
	double _sin = sin(rotate_rad);

	CPoint vertex_pt, vertex_pt2[4];

	// 4 corner of the image (rotating between the center of the image catches up to the origin.)
	// For each vertex for a given angle of rotation is performed.
	vertex_pt = CPoint( - double(width) / 2. ,  - double(height) / 2. );
	vertex_pt2[0].x = (long) (_cos * vertex_pt.x - _sin * vertex_pt.y);
	vertex_pt2[0].y = (long)(_sin * vertex_pt.x + _cos * vertex_pt.y);

	vertex_pt =  CPoint( double(width) / 2. , - double(height) / 2. );
	vertex_pt2[1].x = (long)(_cos * vertex_pt.x - _sin * vertex_pt.y);
	vertex_pt2[1].y = (long)(_sin * vertex_pt.x + _cos * vertex_pt.y);

	vertex_pt =  CPoint( double(width) / 2. , double(height) / 2. );
	vertex_pt2[2].x = (long)(_cos * vertex_pt.x - _sin * vertex_pt.y);
	vertex_pt2[2].y = (long)(_sin * vertex_pt.x + _cos * vertex_pt.y);

	vertex_pt =  CPoint( - double(width) / 2. , double(height) / 2. );
	vertex_pt2[3].x = (long)(_cos * vertex_pt.x - _sin * vertex_pt.y);
	vertex_pt2[3].y = (long)(_sin * vertex_pt.x + _cos * vertex_pt.y);

	// 4 corner after conversion from the new image's width and height save.
	// I do not know a better way?
	width_new = max( max( max( vertex_pt2[0].x, vertex_pt2[1].x ), vertex_pt2[2].x ), vertex_pt2[3].x )
		- min( min( min( vertex_pt2[0].x, vertex_pt2[1].x ), vertex_pt2[2].x ), vertex_pt2[3].x );

	height_new = max( max( max( vertex_pt2[0].y, vertex_pt2[1].y ), vertex_pt2[2].y ), vertex_pt2[3].y )
		- min( min( min( vertex_pt2[0].y, vertex_pt2[1].y ), vertex_pt2[2].y ), vertex_pt2[3].y );

	IplImage* pIPLImage = iplCloneImage(m_pIPLImage);

	if (m_pIPLImage)
		iplDeallocateImage(m_pIPLImage);

	if (GetBitCount() == 8)
	{
		m_pIPLImage = iplCreateImageHeader(1, 0, IPL_DEPTH_8U, "Gray", "GRAY", IPL_DATA_ORDER_PIXEL, 
			IPL_ORIGIN_TL, IPL_ALIGN_DWORD,width, height, NULL, NULL,NULL, NULL);
	}
	else //if (GetBitCount() == 24)
	{
		m_pIPLImage = iplCreateImageHeader(3, 0, IPL_DEPTH_8U, "RGB", "BGR", IPL_DATA_ORDER_PIXEL,
			IPL_ORIGIN_BL, IPL_ALIGN_DWORD, width_new, height_new, NULL, NULL, NULL, NULL);
	}

	iplAllocateImage( m_pIPLImage, 1, 255 );
	
	// affine coefficient of shift-> rotate, you will order is determined.
	// New image in the original coordinates of the center point of the image (go to the center of rotation vector) plus
	// Center rotated after the origin of the original image corresponding to the vector (pt.0) is the sum of that shift. 
	const double affine_coeff[2][3] = {_cos, -_sin, double(width_new)/2. + vertex_pt2[0].x,
									_sin, _cos, double(height_new)/2. + vertex_pt2[0].y};

	IplROI* roi = iplCreateROI(0, height - pIPLImage->roi->yOffset - pIPLImage->roi->height, pIPLImage->roi->xOffset, pIPLImage->roi->height, pIPLImage->roi->width);

	IplROI* roi2 = iplCreateROI(0, 0, 0, pIPLImage->width, pIPLImage->height);
	IplROI* roi3 = iplCreateROI(0, 0, 0, width_new, height_new);

	if (pIPLImage->roi)
	{
		iplDeleteROI(pIPLImage->roi);
	}
	if (m_pIPLImage->roi)
	{
		iplDeleteROI(m_pIPLImage->roi);
	}
	
	pIPLImage->roi = roi2;
	m_pIPLImage->roi = roi3;

	iplWarpAffine(pIPLImage, m_pIPLImage, affine_coeff, IPL_INTER_LINEAR);

	if (m_pIPLImage->roi)
	{
		iplDeleteROI(m_pIPLImage->roi);
	}
	
	m_pIPLImage->roi = roi;

	//Delete pIPLImage
	iplDeallocate( pIPLImage, IPL_IMAGE_ALL );
    
	if (iplGetErrStatus() != IPL_StsOk )
		return 0;
	else
		return 1;
}

int CIPLImage::GetBitCount()
{
	if (m_pIPLImage == NULL) return -1;

	return (DWORD)(8 * m_pIPLImage->nChannels);
}

#if !defined(AFX_IPLIMAGE_H__656BCBF9_3D76_49FD_AFA5_ED551432F660__INCLUDED_)
#define AFX_IPLIMAGE_H__656BCBF9_3D76_49FD_AFA5_ED551432F660__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "ipl.h"

class CIPLImage  
{
public:
	CIPLImage();
	virtual ~CIPLImage();
// Attributes
public:
	IplImage* m_pIPLImage;
	int		  m_clone;

// Operations
public:
	bool Create(int width, int height,int depth);
	void Free();
	bool OpenWithDIB(BITMAPINFOHEADER* bmphdr);

	BITMAPINFO* GetbmpInfo();
	bool Draw(HDC hDC, LPRECT lpDCRect);
	bool SetROI(int xOffset, int yOffset, int width, int height);

	int GetHeight()			{return m_pIPLImage->height;}
	int GetWidth()			{return m_pIPLImage->width;}
	int GetBitCount();

	//Image Orientation 
	void InvertRL();	//flip vertically
	void InvertHF();	//flip horizontally
	BOOL RotateRight();	//rotate +90 deg
	BOOL RotateLeft();	//rotate -90 deg
	BOOL RotateAngle(double rotate_rad);	//rotate arbitrary angle
};

#endif // !defined(AFX_IPLIMAGE_H__656BCBF9_3D76_49FD_AFA5_ED551432F660__INCLUDED_)


simeon
Site Admin
Posts: 233
Joined: Thu Jan 01, 1970 2:00 am
Location: Bulgaria
Contact:

Re: coding rotation any angle

Post by simeon » Mon Oct 19, 2009 8:49 am

Cutun thanks for code

Post Reply