opencv putText中文乱码

https://mangoroom.cn/opencv/opencv-puttext-chinese-characters.html

https://stackoverflow.com/questions/45116828/opencv-cvaddtext-exception-if-no-window

opencv不支持渲染中文字符的原由
opencv不支持渲染中文字符的本质是不支持对utf-8的字符渲染,opencv库中的cv::putText()函数仅支持对ascii码,这是一个很小的字符编码,想要支持中文或者其他字符的渲染就需要支持Unicode的字符集。其实早期的opencv是字符Unicode的字符渲染的,在c语言版本时代采用的是FreeType库实现的,但由于FreeFype是GPL版权发布的库,和OpenCV版权并不一致,因此目前还没有合并到OpenCV

解决方法:

编译opencv的时候,勾选wiht Qt的选项,因为Qt的渲染是支持Unicode字符集的,所以在编译opencv的时候联合编译qt的部分代码可以实现对Unicode的支持。将qt添加到opencv里一起编译本是一件比较麻烦的事,所幸的是opencv官方已经替我们解决了,已经将此选项写在了cmake的构建文件里。所以在编译的时候只需要我们勾选即可。而且在qt的官网可以找到编译教程,教程地址:
https://wiki.qt.io/How_to_setup_Qt_and_openCV_on_Windows

简单地说,参考教程,只需要在编译opencv的时候,勾选以下两个选项即可

WITH_QT
WITH_OPENGL

Mat img = imread("lena.jpg");
cv::addText(img, "中文测试", cv::Point(100, 50), cv::fontQt("Times"));
imwrite("res.bmp", img);

/home/vitaly/CLionProjects/opencvTest/cmake-build-debug/opencvTest /home/vitaly/Pictures/img.jpg OpenCV Error: Null pointer (NULL guiReceiver (please create a window)) in cvAddText, file /home/vitaly/Documents/opencv/opencv/modules/highgui/src/window_QT.cpp, line 114 terminate called after throwing an instance of 'cv::Exception' what(): /home/vitaly/Documents/opencv/opencv/modules/highgui/src/window_QT.cpp:114: error: (-27) NULL guiReceiver (please create a window) in function cvAddText

which goes away if I add

namedWindow("test", WINDOW_AUTOSIZE);

before addText.

However, I cannot understand why would qt or opencv need an opened window for that ? I don't need to display the image, I'm only using it to put text on image and then save it, I don't want to create any windows.

So here's my questions

  1. Why window is required for that ?
  2. Is there a way around it ? (To not create windows)

As you can see in the source code:

CV_IMPL void cvAddText(const CvArr* img, const char* text, CvPoint org, CvFont* font)
{
    if (!guiMainThread)
        CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" );

    QMetaObject::invokeMethod(guiMainThread,
        "putText",
        autoBlockingConnection(),
        Q_ARG(void*, (void*) img),
        Q_ARG(QString,QString::fromUtf8(text)),
        Q_ARG(QPoint, QPoint(org.x,org.y)),
        Q_ARG(void*,(void*) font));
}

addText requires a gui thread. as the actual drawing happens in that thread. No thread, no function, no drawing...

Why is it like that? Well because it made sense to somebody I guess.

It's open source, feel free to code your own workaround. Otherwise use OpenCV's putText.

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

friendan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值