C++のOpenCVで日本語をputTextする
Pythonの場合比較的容易にできる、日本語を画面描画する方法。
C++はそういったことができないので非常に困っていた。
で、ネットからパクったりして以下を作成。
cv::putTextライクに日本語が使える。
日本語版putText
■コード
(第三引数のfontnameには、'MS ゴシック'などのフォント名を入れる)
void _putText(cv::Mat& img, const cv::String& text, const cv::Point& org, const char* fontname, double fontScale, cv::Scalar color)
{
int fontSize = (int)(10 * fontScale); // 10は適当
int width = img.cols;
int height = fontSize * 3 / 2; // 高さはフォントサイズの1.5倍
HDC hdc = ::CreateCompatibleDC(NULL);
BITMAPINFOHEADER header;
::ZeroMemory(&header, sizeof(BITMAPINFOHEADER));
header.biSize = sizeof(BITMAPINFOHEADER);
header.biWidth = width;
header.biHeight = height;
header.biPlanes = 1;
header.biBitCount = 24;
BITMAPINFO bitmapInfo;
bitmapInfo.bmiHeader = header;
HBITMAP hbmp = ::CreateDIBSection(NULL, (LPBITMAPINFO)&bitmapInfo, DIB_RGB_COLORS, NULL, NULL, 0);
::SelectObject(hdc, hbmp);
BITMAP bitmap;
::GetObject(hbmp, sizeof(BITMAP), &bitmap);
int back_color = 0x99;
int memSize = (((bitmap.bmBitsPixel / 8) * width) & ~3) * height;
std::memset(bitmap.bmBits, back_color, memSize);
HFONT hFont = ::CreateFontA(
fontSize, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE,
SHIFTJIS_CHARSET, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
VARIABLE_PITCH | FF_ROMAN, fontname);
::SelectObject(hdc, hFont);
::TextOutA(hdc, 0, height / 3 * 1, text.c_str(), (int)text.length());
int posX = org.x;
int posY = org.y - fontSize;
unsigned char* _tmp;
unsigned char* _img;
for (int y = 0; y < bitmap.bmHeight; y++) {
if (posY + y >= 0 && posY + y < img.rows) {
_img = img.data + (int)(3 * posX + (posY + y) * (((bitmap.bmBitsPixel / 8) * img.cols) & ~3));
_tmp = (unsigned char*)(bitmap.bmBits) + (int)((bitmap.bmHeight - y - 1) * (((bitmap.bmBitsPixel / 8) * bitmap.bmWidth) & ~3));
for (int x = 0; x < bitmap.bmWidth; x++) {
if (x + posX >= img.cols) {
break;
}
if (_tmp[0] == 0 && _tmp[1] == 0 && _tmp[2] == 0) {
_img[0] = (unsigned char)color.val[0];
_img[1] = (unsigned char)color.val[1];
_img[2] = (unsigned char)color.val[2];
}
_img += 3;
_tmp += 3;
}
}
}
::DeleteObject(hFont);
::DeleteObject(hbmp);
::DeleteDC(hdc);
}
以上!