Вывод русского текста на картинку OpenCV в Windows при помощи HBITMAP / OpenCV / Recog.ru - Распознавание образов для программистов


Вывод русского текста на картинку OpenCV в Windows при помощи HBITMAP

Если мы хотим вывести русский текст с произвольным шрифтом на картинку OpenCV или воспользоваться другими функциями GDI, то можно использовать для этого HBITMAP. Ниже рассмотрен пример вывода текста на русском языке, результат которого дает следующее:

Первоначально понадобится функция, которая переводит IplImage в HBITMAP. Для этого можно воспользоваться следующей:
#define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4)
HBITMAP CreateRGBBitmap(IplImage* _Grab,HDC hDC, char** ptr)
{
    char *App;
    LPBITMAPINFO lpbi = new BITMAPINFO;
    lpbi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    lpbi->bmiHeader.biWidth = _Grab->width;
    lpbi->bmiHeader.biHeight =_Grab->height;
    lpbi->bmiHeader.biPlanes = 1;
    lpbi->bmiHeader.biBitCount = 24;
    lpbi->bmiHeader.biCompression = BI_RGB;
    lpbi->bmiHeader.biSizeImage = WIDTHBYTES((DWORD)_Grab->width * 8) * _Grab->height;
    lpbi->bmiHeader.biXPelsPerMeter = 0;
    lpbi->bmiHeader.biYPelsPerMeter = 0;
    lpbi->bmiHeader.biClrUsed = 0;
    lpbi->bmiHeader.biClrImportant = 0;
    void* pBits;
    HBITMAP hBitmap = CreateDIBSection( hDC,lpbi,DIB_RGB_COLORS,(void **)&pBits,NULL,0 );
    delete lpbi;
    if ( hBitmap ) App=(char*)pBits;
	long int length=0;
    if(_Grab->nChannels==1) // Серое или бинарное
    {
           length = _Grab->width*(_Grab->height);
           for (int i=0;i<_Grab->height;i++)
           {
                   for (int j=0;j<_Grab->width;j++)
                   {
                           App[_Grab->width*3*(_Grab->height-i-1)+j*3]=_Grab->imageData[_Grab->width*(i)+j];
                           App[_Grab->width*3*(_Grab->height-i-1)+j*3+1]=_Grab->imageData[_Grab->width*(i)+j];
                           App[_Grab->width*3*(_Grab->height-i-1)+j*3+2]=_Grab->imageData[_Grab->width*(i)+j];
                   }
           }
    }
    if(_Grab->nChannels==3) // Цветное
    {
           for (int i=0;i<_Grab->height;i++)
           {
                   // Копируем память
                   memcpy(App+_Grab->width*3*(_Grab->height-i-1),_Grab->imageData+_Grab->width*3*i,_Grab->width*3);           
           }
    }	
	(*ptr) = App;
    return hBitmap;
}


Помимо OpenCV изображения функция принимает HDC, который будет использоваться для рисования, а также указатель, который будет указывать на графическое изображение. Функция переворачивает изображение OpenCV, поскольку в HBITMAP оно хранится (как и в BMP) вверх ногами. Ниже представлен листинг, в котором на исходное изображение (OutImage) выводится сверху текст.
HFONT font = CreateFont( 20, 0, 0, 0,
	FW_NORMAL, FALSE, FALSE, FALSE,
	RUSSIAN_CHARSET,
	OUT_DEFAULT_PRECIS,
	CLIP_DEFAULT_PRECIS,
	DEFAULT_QUALITY,
	VARIABLE_PITCH,
	"times");		  
char *ptr=0;
HDC hDC = CreateCompatibleDC( NULL );
HBITMAP hBitmap = CreateRGBBitmap( OutImage, hDC, &ptr );		  
SelectObject(hDC,hBitmap);
SelectObject( hDC, font );
SetBkMode( hDC, TRANSPARENT );
SetTextColor( hDC, RGB(255,0,0) ); 		  	  
RECT rect;
rect.left = 100;
rect.top = 100;
rect.bottom = 200;
rect.right = 200;
DrawText(hDC, "Привет!", 7, &rect, DT_LEFT | DT_WORDBREAK);		  
DeleteObject( font );		  
ReleaseDC(NULL, hDC);
for( int i = 0; i < OutImage->height; i++)
  memcpy( &OutImage->imageData[(OutImage->height-1-i)*OutImage->widthStep],
      &ptr[i*OutImage->widthStep],OutImage->widthStep);		  
DeleteObject( hBitmap );	

В начале создается шрифт, какой нужно. Затем получается HBITMAP, на который выводится текст. После чего опять происходит копирование вOutImage (опять переворот изображения).
  • 0
  • 22 октября 2012, 11:39
  • vidikon

Комментарии (0)

RSS свернуть / развернуть

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.