www.pudn.com > Gesture[20040824].rar > Image.cpp
// Image.cpp: implementation of the CImage class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "Image.h" #include#include using namespace std; #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[] = __FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CImage::CImage() { Clear(); } void CImage::Clear() { memset( &m_img, 0, sizeof(m_img)); m_memDC = 0; m_old = 0; } void CImage::Destroy() { if( m_memDC ) { DeleteObject( SelectObject( m_memDC, m_old )); DeleteDC( m_memDC ); } Clear(); } CImage::~CImage() { Destroy(); } void FillBitmapInfo( BITMAPINFO* bmi, int width, int height, int bpp ) { ASSERT( bmi && width > 0 && height > 0 && (bpp == 8 || bpp == 24 || bpp == 32) ); BITMAPINFOHEADER* bmih = &(bmi->bmiHeader); memset( bmih, 0, sizeof(*bmih)); bmih->biSize = sizeof(BITMAPINFOHEADER); bmih->biWidth = width; bmih->biHeight = -abs(height); bmih->biPlanes = 1; bmih->biBitCount = bpp; bmih->biCompression = BI_RGB; if( bpp == 8 ) { RGBQUAD* palette = bmi->bmiColors; int i; for( i = 0; i < 256; i++ ) { palette[i].rgbBlue = palette[i].rgbGreen = palette[i].rgbRed = (BYTE)i; palette[i].rgbReserved = 0; } } } bool CImage::Create( int w, int h, int bpp ) { char buffer[sizeof(BITMAPINFOHEADER) + 1024]; BITMAPINFO* bmi = (BITMAPINFO*)buffer; void* data = 0; int new_step = (w*(bpp/8) + 3) & -4; ASSERT( bpp == 8 || bpp == 24 || bpp == 32 ); bool AlphaChannel = bpp==32; if( (m_img.depth & 255) == bpp && m_img.width == w && m_img.height == h ) { return true; } Destroy(); m_memDC = CreateCompatibleDC(0); FillBitmapInfo( bmi, w, h, bpp ); HBITMAP hbmp = CreateDIBSection( m_memDC, bmi, DIB_RGB_COLORS, &data, 0, 0 ); if( !hbmp ) { DeleteDC( m_memDC ); m_memDC = 0; } else { BITMAP bmp; m_old = SelectObject( m_memDC, hbmp ); GetObject( hbmp, sizeof(bmp), &bmp ); /* prepare IPL header */ memset( &m_img, 0, sizeof(m_img)); m_img.nSize = sizeof( m_img ); m_img.nChannels = bpp/8; m_img.depth = IPL_DEPTH_8U; strncpy( m_img.colorModel, bpp > 8 ? "RGB\0" : "GRAY", 4 ); strncpy( m_img.channelSeq, bpp > 8 ? "BGR\0" : "GRAY", 4 ); m_img.align = 8;///////////////////////////////////////////////// m_img.width = w; m_img.height = abs(h); m_img.roi = 0; m_img.widthStep = (w*(bpp/8) + 3)& -4; m_img.imageSize = m_img.widthStep*m_img.height; m_img.imageData = m_img.imageDataOrigin = (char*)bmp.bmBits; iplSetBorderMode( &m_img, IPL_BORDER_REPLICATE, IPL_SIDE_ALL, 0 ); } return m_old != 0; } void CImage::CopyOf( CImage& image, int desired_color ) { IplImage* img = image.GetImage(); if( img ) { int color = desired_color; if( color < 0 ) color = img->nChannels > 1; Create( img->width, img->height, color ? 24 : 8 ); if( m_img.nChannels == img->nChannels ) iplCopy( img, &m_img ); else { CImage tmp_image; tmp_image.Create( m_img.width, m_img.height, img->nChannels*8 ); IplImage* tmp_img = tmp_image.GetImage(); iplCopy( img, tmp_img ); if( color ) iplGrayToColor( tmp_img, &m_img, 0, 0, 0 ); else iplColorToGray( tmp_img, &m_img ); } } } bool CImage::LoadBMP2IPL( const char* filename, bool IsColor ) { int filter = 0; int width = 0, height = 0; bool result = false; int color = 55; if( gr_fmt_find_filter == 0 ) return false; if( !(filter = gr_fmt_find_filter( filename ))) goto exit; if( !gr_fmt_read_header( filter, &width, &height, &color )) goto exit; Create( width, height, IsColor ? 24 : 8); if( m_memDC == 0 ) goto exit; if (IsColor==0)color=0; result = gr_fmt_read_data( filter, m_img.imageData, m_img.widthStep, color ) != 0; exit: gr_fmt_close_filter( filter ); return result; } bool CImage::LoadRect( const char* filename, int desired_color, RECT r ) { int filter = 0; int width = 0, height = 0; bool result = false; int color = 0; int r_width = r.right - r.left; int r_height = r.bottom - r.top; int tmp_step = 0; char* tmp = 0; if( r_width < 0 || r_height < 0 ) return false; if( gr_fmt_find_filter == 0 ) return false; if( !(filter = gr_fmt_find_filter( filename ))) goto exit; if( !gr_fmt_read_header( filter, &width, &height, &color )) goto exit; if( r_width == 0 || r_height == 0 ) { r_width = width; r_height = height; } if( (unsigned)r.left >= (unsigned)width || (unsigned)r.top >= (unsigned)height || (unsigned)r.right >= (unsigned)width || (unsigned)r.bottom >= (unsigned)height ) goto exit; color = desired_color >= 0 ? desired_color : color > 0; Create( r_width, r_height, color ? 24 : 8); if( m_memDC == 0 ) goto exit; if( r.left == 0 && r.top == 0 && (r_width == 0 || r_width == width) && (r_height == 0 || r_height == height)) { tmp = m_img.imageData; tmp_step = m_img.widthStep; } else { tmp_step = (width*m_img.nChannels + 3) & -4; tmp = (char*)malloc( tmp_step * height ); if( !tmp ) goto exit; } result = gr_fmt_read_data( filter, tmp, tmp_step, color ) != 0; if( result && tmp != m_img.imageData ) { int y; for( y = 0; y < r_height; y++ ) { memcpy( m_img.imageData + y*m_img.widthStep, tmp + (r.top + y)*tmp_step + r.left*m_img.nChannels, r_width * m_img.nChannels ); } } exit: gr_fmt_close_filter( filter ); if( tmp != 0 && tmp != m_img.imageData ) free( tmp ); return result; } void CImage::LoadIPL2IPL(IplImage *image) { Create(image->width, image->height, image->nChannels*8); cvCopyImage(image, &m_img); } void CImage::SaveIPL2BMP(const char *fout, IplImage *image) { if ( (image->nChannels != 3 && image->nChannels != 1) || image->depth != IPL_DEPTH_8U ) return; gr_fmt_write_image( image->imageData, image->widthStep, iplWidth( image ), iplHeight( image ), image->nChannels == 3, fout, "BMP" ); } void CImage::Show( HDC dc, int x, int y) { Show(dc, x,y,Width(),Height(),0,0 ); } void CImage::Show( HDC dc, int x, int y, int w, int h, int from_x, int from_y ) { if( m_img.width > 0 ) { uchar buffer[sizeof(BITMAPINFOHEADER) + 1024]; BITMAPINFO* bmi = (BITMAPINFO*)buffer; int bmp_w = Width(); int bmp_h = Height(); FillBitmapInfo( bmi, bmp_w, bmp_h, m_img.nChannels*8 ); int sw = MAX( MIN( bmp_w - from_x, w ), 0 ); int sh = MAX( MIN( bmp_h - from_y, h ), 0 ); int res = SetDIBitsToDevice( dc, // handle to DC x, // x-coord of destination upper-left corner y, // y-coord of destination upper-left corner sw, // source rectangle width sh, // source rectangle height from_x, // x-coord of source lower-left corner from_y, // y-coord of source lower-left corner from_y, // first scan line in array sh, // number of scan lines m_img.imageData + from_y*m_img.widthStep/* + from_x*m_img.nChannels*/, // array of DIB bits (BITMAPINFO*)bmi, // bitmap information DIB_RGB_COLORS ); // RGB or palette indexes } } void CImage::Fill( COLORREF color ) { if( m_memDC ) { HBRUSH br = CreateSolidBrush( color ); RECT rect; GetClipBox( m_memDC, &rect ); FillRect( m_memDC, &rect, br ); DeleteObject( br ); } } IplImage *Getchannel(IplImage *image,int channel) { ASSERT(channel>= 0&&channel<3); IplROI *ROI; CvSize size; size.width = image->width; size.height = image->height; ROI = iplCreateROI(0, 0, 0, 0, 0); IplImage *channelimg = cvCreateImage(size,8,1); iplSetROI(ROI,channel+1, 0, 0, size.width,size.height); image->roi = ROI; iplCopy(image,channelimg); image->roi = NULL; iplDeleteROI(ROI); return channelimg; } IplImage *GetBchannel(IplImage *image) { return Getchannel(image,0); } IplImage *GetGchannel(IplImage *image) { return Getchannel(image,1); } IplImage *GetRchannel(IplImage *image) { return Getchannel(image,2); } CSize CImage::GetSize() { return CSize(Width(),Height()); } void CImage::Save2Bmp(const char * filename) { SaveIPL2BMP(filename,&m_img); } CImage * CImage::GetRect(CRect a) { CImage * output=new CImage(); IplROI *ROI1; ROI1 = iplCreateROI(0, a.left ,a.top, a.Width(),a.Height()); m_img.roi = ROI1; output->Create(a.Width(),a.Height(),24); iplCopy(&m_img,&output->m_img); m_img.roi = NULL; iplDeleteROI(ROI1); return output; } void drawrectangle(CPoint p1, CPoint p2, COLORREF color, CDC * pDC,int method) { int meth; if (method==0)meth=PS_SOLID; else meth=PS_DOT; CPen penBlack; penBlack.CreatePen(meth, 1, color); CPen* pOldPen = pDC->SelectObject(&penBlack); CRect m_rect(p1,p2); pDC->MoveTo(m_rect.left,m_rect.top); pDC->LineTo(m_rect.left,m_rect.bottom); pDC->LineTo(m_rect.right,m_rect.bottom); pDC->LineTo(m_rect.right,m_rect.top); pDC->LineTo(m_rect.left,m_rect.top); pDC->SelectObject(pOldPen); } void CImage::Mean(int color[3],CRect rectoi) { IplROI *ROI1; ROI1 = iplCreateROI(0,rectoi.left,rectoi.top,rectoi.Width(),rectoi.Height()); for (int i=0;i<3;i++) {iplSetROI(ROI1,i+1,rectoi.left,rectoi.top,rectoi.Width(),rectoi.Height()); m_img.roi = ROI1; color[i]=cvMean(&m_img); } m_img.roi=NULL; iplDeleteROI(ROI1); } void Thinning(IplImage *Img,CvSize size) { static int erasetable[256]={ 0,0,0,1,0,0,1,1, 0,1,1,1,0,0,1,1, 0,0,1,1,1,0,1,1, 0,0,1,1,0,0,1,1, 0,0,0,0,0,0,0,0, 1,1,1,1,0,0,1,1, 0,0,0,0,0,0,0,0, 0,0,1,1,0,0,1,1, 0,0,0,0,0,0,0,0, 1,1,1,1,0,0,1,1, 1,0,1,1,1,0,1,1, 1,1,0,0,1,1,0,0, 1,0,0,0,0,0,0,0, 1,1,1,1,0,0,1,1, 1,0,1,1,1,0,1,1, 1,1,0,0,1,1,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,0,1,1,1,0,1,1, 0,0,1,1,0,0,1,1, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,1,1,0,0,1,1, 1,0,0,0,0,0,0,0, 1,1,1,1,0,0,1,1, 1,0,1,1,1,0,1,1, 1,1,0,0,1,1,0,0, 1,0,0,0,0,0,0,0, 1,1,1,1,0,0,1,1, 1,0,1,1,1,0,1,1, 1,1,0,0,1,1,0,0 }; int x,y; int num; int Finished; int nw,n,ne,w,e,sw,s,se; IplImage *tImg; char *ImgStart, *tImgStart, *lpPtr, *lpTempPtr; int LineBytes; LineBytes = Img->width; tImg = cvCreateImage(size, 8, 1); iplCopy(Img, tImg); ImgStart = Img->imageData; tImgStart = Img->imageData; Finished=FALSE; while(!Finished){ Finished=TRUE; for (y=1; y height-1;y++) { lpPtr = ImgStart + y*LineBytes; lpTempPtr = tImgStart + y*LineBytes; x=1; while(x width-1) { if(*(lpPtr+x)){ w=(BYTE)*(lpPtr+x-1)?255:0; e=(BYTE)*(lpPtr+x+1)?255:0; if( (w==0)|| (e==0)){ nw=(unsigned char)*(lpPtr+x+LineBytes-1)?255:0; n=(unsigned char)*(lpPtr+x+LineBytes)?255:0; ne=(unsigned char)*(lpPtr+x+LineBytes+1)?255:0; sw=(unsigned char)*(lpPtr+x-LineBytes-1)?255:0; s=(unsigned char)*(lpPtr+x-LineBytes)?255:0; se=(unsigned char)*(lpPtr+x-LineBytes+1)?255:0; num=nw/255+n/255*2+ne/255*4+w/255*8+e/255*16+sw/255*32+s/255*64+se/255*128; if(erasetable[num]==1){ *(lpPtr+x)= 0; *(lpTempPtr+x)= 0; Finished=FALSE; x++; } } } x++; } } for (x=1;x width-1;x++){ y=1; while(y height-1){ lpPtr = ImgStart + y*LineBytes; lpTempPtr = tImgStart + y*LineBytes; if(*(lpPtr+x)){ n=(unsigned char)*(lpPtr+x+LineBytes)?255:0; s=(unsigned char)*(lpPtr+x-LineBytes)?255:0; if( (n==0)|| (s==0)){ nw=(unsigned char)*(lpPtr+x+LineBytes-1)?255:0; ne=(unsigned char)*(lpPtr+x+LineBytes+1)?255:0; w=(unsigned char)*(lpPtr+x-1)?255:0; e=(unsigned char)*(lpPtr+x+1)?255:0; sw=(unsigned char)*(lpPtr+x-LineBytes-1)?255:0; se=(unsigned char)*(lpPtr+x-LineBytes+1)?255:0; num=nw/255+n/255*2+ne/255*4+w/255*8+e/255*16+sw/255*32+s/255*64+se/255*128; if(erasetable[num]==1){ *(lpPtr+x)=0; *(lpTempPtr+x)=0; Finished=FALSE; y++; } } } y++; } } }//end of while cvReleaseImage(&tImg); } /*ipl 应用函数 (非cimage类成员函数)*/ /*typedef enum { Error = -1, Fail = 0, Good = 1 } ipStatus; //static ThreadDataArray g_threads; BITMAPINFOHEADER* ipLoad( const char* fname ) { if( !fname ) return NULL; BITMAPINFOHEADER *infohdr = NULL; ifstream fsrc; try { BITMAPFILEHEADER filehdr; BITMAPINFOHEADER bmphdr; fsrc.open( fname, ios::in | ios::binary ); if( fsrc.fail() ) throw runtime_error("Problem to open source file"); fsrc.read( (char*)&filehdr, sizeof(BITMAPFILEHEADER) ); if( fsrc.fail() ) throw runtime_error("Problem to read bmp-file header from source file"); if( 0x4d42 != filehdr.bfType ) throw runtime_error("Wrong type of source file"); fsrc.read( (char*)&bmphdr, sizeof(BITMAPINFOHEADER) ); if( fsrc.fail() ) throw runtime_error("Problem to read bmp-header from source file"); if( 0 == bmphdr.biSizeImage ) bmphdr.biSizeImage = (((( bmphdr.biWidth * bmphdr.biBitCount ) + 31) & ~31) >> 3) * bmphdr.biHeight; if( 0 == bmphdr.biClrUsed ) { if( BI_BITFIELDS == bmphdr.biCompression ) bmphdr.biClrUsed = 3; else bmphdr.biClrUsed = bmphdr.biBitCount < 16 ? 1 << bmphdr.biBitCount : 256; } int colorbytes = sizeof(RGBQUAD) * bmphdr.biClrUsed; int totalbytes = sizeof(BITMAPINFOHEADER) + colorbytes + bmphdr.biSizeImage; infohdr = (BITMAPINFOHEADER*)malloc( totalbytes ); if( !infohdr ) throw runtime_error("Problem to allocate memory for DIB data"); char* quads = (char*)infohdr + sizeof(BITMAPINFOHEADER); char* pixels = (char*)quads + colorbytes; memcpy( infohdr, &bmphdr, sizeof( bmphdr) ); fsrc.read( (char*)quads, colorbytes ); fsrc.read( (char*)pixels, bmphdr.biSizeImage ); fsrc.close(); } catch( runtime_error e ) { TRACE0( e.what() ); if( infohdr ) { free( infohdr ); infohdr = 0; } } return infohdr; } IplImage* cloneImageHeader( const IplImage* src, int width, int height ) { IplImage* clone = NULL; if( src ) { clone = iplCreateImageHeader( src->nChannels, src->alphaChannel, src->depth, (char*)src->colorModel, (char*)src->channelSeq, src->dataOrder, src->origin, src->align, width, height, NULL, NULL, NULL, NULL); } return clone; } IplImage* cloneImageHeader( const IplImage* src ) { if( !src ) return NULL; return cloneImageHeader( src, src->width, src->height ); } void ipInflateRoi( IplROI *roi, int step ) { roi->xOffset -= step; roi->yOffset -= step; roi->width += (step*2); roi->height += (step*2); } int ipSetImageROI( IplImage *img, int coi, int x, int y, int w, int h ) { if( !img ) return 0; if( !img->roi ) img->roi = iplCreateROI( coi, x,y, w,h ); else iplSetROI( img->roi, coi, x,y, w,h ); return !img->roi; } int ipSetROItoWholeImage( IplImage *img ) { if( !img ) return 0; img->roi = iplCreateROI( 0, 0,0, img->width, img->height ); return !img->roi; } extern "C" __int64 winrdtsc(); __int64 getPentiumCounter() { // winrdtsc(); __asm mov ecx, edx __asm mov edx, eax __asm mov eax, ecx } static ipStatus ipDraw( HDC hdc, IplImage* img ) { if( !img || !img->imageData ) return Error; bool isrgb = 'R' == toupper( img->colorModel[0] ) && 'G' == toupper( img->colorModel[1] ) && 'B' == toupper( img->colorModel[2] ); bool isgray = 'G' == toupper( img->colorModel[0] ); if( !isgray && !isrgb ) return Fail; if( (1 == img->nChannels) != isgray ) return Fail; 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 = img->width; dibhdr->biHeight = img->height; dibhdr->biPlanes = 1; dibhdr->biBitCount = (DWORD)(8 * img->nChannels); dibhdr->biCompression = BI_RGB; dibhdr->biSizeImage = img->imageSize; dibhdr->biXPelsPerMeter = 0; dibhdr->biYPelsPerMeter = 0; dibhdr->biClrUsed = 0; dibhdr->biClrImportant = 0; ::SetDIBitsToDevice( hdc, 0,0,img->width,img->height, 0,0,0,img->height, img->imageData, (BITMAPINFO*)dibhdr, DIB_RGB_COLORS ); return Good; } HANDLE ipView( const IplImage* img, const char* caption, bool isModalView ) { if( !img ) return 0; if( g_threads.isfull() ) { MessageBox( NULL, "Too many threads are beign executed. " "Please decrease number of viewers or use Modal mode.", g_name, MB_OK | MB_ICONSTOP ); return 0; } IplImage *clone = NULL, *img8u = NULL; HANDLE hThread = 0; /// Note we need not clone in the DEPTH_1U case if( NULL == (clone = iplCloneImage( img ))) return 0; /// Since this moment we should take care about clone pointer try { /// Create header for the image to be drawn img8u = iplCreateImageHeader( img->nChannels, img->alphaChannel, IPL_DEPTH_8U, /// fixed 8u (char*)img->colorModel, (char*)img->channelSeq, IPL_DATA_ORDER_PIXEL, /// fixed pixel img->origin, IPL_ALIGN_DWORD, img->width, img->height, NULL, NULL, NULL, NULL ); if( !img8u ) throw bexception( false ); iplAllocateImage( img8u, 0,0 ); if( !img8u->imageData ) throw bexception( true ); /// convert to 8u,plane image for viewing if( IPL_DEPTH_1U == img->depth ) iplBitonalToGray( (IplImage*)img, img8u, 0,255 ); else if( IPL_DEPTH_8U != img->depth ) iplScale( img, img8u ); else iplCopy( (IplImage*)img, img8u ); if( IPL_StsOk != iplGetErrStatus()) throw bexception( true ); static ThreadData param; lstrcpy( param.text, NULL == caption ? "IPLib image" : caption ); param.img = img8u; param.isModalView = isModalView; /// prepare for wainting ::ResetEvent( g_threads.m_hevent ); hThread = CreateThread( NULL, // pointer to thread security attributes 0, // initial thread stack size, in bytes (LPTHREAD_START_ROUTINE) ViewerThread, // pointer to thread function (LPVOID)(0), // argument for new thread 0, // creation flags, runs immediately ¶m.id); // pointer to returned thread identifier if( !hThread ) throw bexception( true ); /// set thread data for thread has been started if( false == g_threads.open( param )) { ::CloseHandle( hThread ); throw bexception( true ); } if( isModalView ) { /// wait for the thread will be ended ::WaitForSingleObject( hThread, INFINITE ); ::CloseHandle( hThread ); return 0; } else /// wait for dialog window will be initialized /// thread will be alive after that ::WaitForSingleObject ( g_threads.m_hevent, 10000 ); } catch( bexception e ) { /// if success then img8u is deleted by the close procedure /// when dialog window will be closed by user /// else we should delete img8u if( e.m_should_delete ) iplDeallocate( img8u, IPL_IMAGE_HEADER ); } /// if( clone ) iplDeallocate( clone, IPL_IMAGE_HEADER ); return hThread; } void create_translate_dib( const char* fname ) { BITMAPINFOHEADER* bmphdr = ipLoad( fname ); if( bmphdr ) { int clone; IplImage* img = iplTranslateDIB( bmphdr, &clone ); if( img ) { ipView( img, fname, is_modal ); iplDeallocate( img, clone ? IPL_IMAGE_ALL : IPL_IMAGE_HEADER ); } free( bmphdr ); } else { TRACE0( "Problem to read bmp-file" ); } } void create_convert_dib( const char* fname ) { BITMAPINFOHEADER* bmphdr = ipLoad( fname ); if( bmphdr ) { IplImage* img = iplCreateImageHeader( 3, // number of channels 0, // alpha channel IPL_DEPTH_8U, // data of byte type "RGB", "BGR", // color model and channel seq IPL_DATA_ORDER_PIXEL, // channel arrangement IPL_ORIGIN_TL, // top left orientation IPL_ALIGN_DWORD, // 4 bytes align bmphdr->biWidth, bmphdr->biHeight, NULL, // ROI NULL, NULL, NULL ); // no mask ROI, image ID, not tiled if( img ) { iplConvertFromDIB( bmphdr, img ); ipView( img, fname, is_modal ); iplDeallocate( img, IPL_IMAGE_ALL ); } free( bmphdr ); } else { TRACE0( "Problem to read bmp-file" ); } } void testCOI( IplImage* srcAimg, IplImage* srcBimg, IplImage* dstimg, int roiOffset, int roiSize ) { IplImage* dstimgRGBA = NULL; /// Note that ROI is created in stack and you should not /// use the ALL mode in Deallocate function without /// setting the image COI to NULL. It is useful to know /// but not necessarily to use. IplROI roi = { 1, 0,0, width, height }; __try { dstimgRGBA = iplCreateImageHeader( 4, // number of channels 4, // alpha channel number IPL_DEPTH_8U, // depth of data image "RGBA", "RGBA", // color model and channel sequence IPL_DATA_ORDER_PIXEL, // image is defined as pixels IPL_ORIGIN_TL, // origin is in the top left corner IPL_ALIGN_QWORD, // image width is aligned width, height, // width and height of image &roi, // region of interest NULL, // no mask ROI here NULL, NULL // image id, not tiled ); if( !dstimgRGBA ) return; iplAllocateImage( dstimgRGBA, 1, 128 ); if( !dstimgRGBA->imageData ) return; // Using Channel of Interest, copy one channel at a // time from source to destination for 3 channels. ipSetROItoWholeImage( srcAimg ); ipSetROItoWholeImage( srcBimg ); /// channels 1 and 2 from source A srcAimg->roi->coi = 1; dstimgRGBA->roi->coi = 1; iplCopy( srcAimg, dstimgRGBA ); srcAimg->roi->coi = 2; dstimgRGBA->roi->coi = 2; iplCopy( srcAimg, dstimgRGBA ); /// channel 3 from source B srcBimg->roi->coi = 3; ipSetImageROI( dstimgRGBA, 3, roiOffset, roiOffset, roiSize, roiSize ); iplCopy( srcBimg, dstimgRGBA ); /// copy channel 3 of source to channel 4 (alpha channel) of destination dstimgRGBA->roi->coi = 4; iplCopy( srcAimg, dstimgRGBA ); /// destination image RGBA is copy of channels ipView( dstimgRGBA, "RGBA is copy of A.1 A.2 B.3 A.3", is_modal ); } __finally { /// restore roi ipSetROItoWholeImage( srcAimg ); ipSetROItoWholeImage( srcBimg ); /// set roi to NULL to protect automatic variable against of freeing if( dstimgRGBA) { dstimgRGBA->roi = NULL; iplDeallocate( dstimgRGBA, IPL_IMAGE_ALL ); } } } int countObjects( IplImage *img ) { int x, y; static const int WHITE = 255; // color of an object on enter static const int GRAY = 128; // color of an object on exit unsigned char *prev = (unsigned char*)img->imageData; unsigned char *line = prev + img->widthStep; /// find and fill objects by gray color, label is one white pixel for( y=1; y height; ++y ) { x = 1; while( x < img->width-1 ) { /// check if there is an object if( WHITE == line[x] ) { /// skip first point but maybe we'll return to it int xx = x+1; /// paint the object do { /// check point above and on the left /// paint the first point if we are inside of the object if( 0 != prev[xx-1] || 0 != prev[xx] ) line[x] = GRAY; line[xx++] = GRAY; } while( xx < img->width-1 && WHITE == line[xx] ); x = xx; } else x++; } prev = line; line += img->widthStep; } /// count the marked objects, one white point is one object int count = 0; line = (unsigned char*)img->imageData; for( y=1; y height-1; ++y ) { for( x=1; x width; ++x ) if( WHITE == line[x] ) count++; line += img->widthStep; } return count; } */ unsigned char ** CImage::ProcessArray() {//最多可以处理500 行图象 //仅仅对灰度 static unsigned char* image[500]; for (int i=0;i< m_img.height;i++) { image[i]=(unsigned char *)((m_img.imageData)+i*m_img.width); } return &image[0]; }