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_)