Opencv 将文本添加到ca cv::Mat的更好方法是cv::putText()?

Opencv 将文本添加到ca cv::Mat的更好方法是cv::putText()?,opencv,Opencv,我想在cv::Mat上添加一些文本,但是cv::putText()对我来说不够灵活 软化 我需要在运行时已知的几个像素位置放置可变长度的标签,但是由于cv::putText()总是将输出的原点放在左侧,因此如果位置太靠左侧,我的文本将消失在图像边界之外 我找不到cv::putText()的替代品。有吗 我只要知道输出文本的宽度和高度(以像素为单位),就可以自己调整位置 更好的方法是,我可以将文本的原点指定在右侧、左侧或中间(垂直和水平) 科托尔 作为奖励,我想用等高线绘制文本,例如带黑色等高线的

我想在
cv::Mat
上添加一些文本,但是
cv::putText()
对我来说不够灵活

软化 我需要在运行时已知的几个像素位置放置可变长度的标签,但是由于
cv::putText()
总是将输出的原点放在左侧,因此如果位置太靠左侧,我的文本将消失在图像边界之外

我找不到
cv::putText()
的替代品。有吗

我只要知道输出文本的宽度和高度(以像素为单位),就可以自己调整位置

更好的方法是,我可以将文本的原点指定在右侧、左侧或中间(垂直和水平)

科托尔
作为奖励,我想用等高线绘制文本,例如带黑色等高线的白色字符,以便您可以在任何背景下阅读它们。

以下是使用freetype和OpenCV的示例:

#include "opencv2/opencv.hpp"

#include "ft2build.h"
#include FT_FREETYPE_H
FT_Library  library;
FT_Face     face;      

using namespace cv;
using namespace std;
//-----------------------------------------------------------------------
void my_draw_bitmap(Mat& img,FT_Bitmap* bitmap,int x,int y, Scalar color)
{
    Scalar src_col,dst_col;
    for(int i=0;i<bitmap->rows;i++)
    {
        for(int j=0;j<bitmap->width;j++)
        {
            unsigned char val=bitmap->buffer[j+i*bitmap->pitch];
            float mix=(float)val/255.0;                              
            if(val!=0)
            {
                src_col=Scalar(img.at<Vec3b>(i+y,j+x));
                dst_col=mix*color+(1.0-mix)*src_col;
                img.at<Vec3b>(i+y,j+x)=Vec3b(dst_col[0],dst_col[1],dst_col[2]);
            }
        }      
    }
}
//-----------------------------------------------------------------------
float PrintString(Mat& img,std::wstring str,int x,int y,Scalar color)
{
    FT_Bool       use_kerning=0;
    FT_UInt       previous=0;
    use_kerning = FT_HAS_KERNING( face );
    float prev_yadv=0;
    float posx=0;
    float posy=0;
    float dx=0;
    for(int k=0;k<str.length();k++)
    {
        int glyph_index = FT_Get_Char_Index( face, str.c_str()[k] );
        FT_GlyphSlot  slot = face->glyph;  // a small shortcut 
        if(k>0){dx=slot->advance.x/64;  }       
        FT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT );
        FT_Render_Glyph (slot,FT_RENDER_MODE_NORMAL);
        prev_yadv=slot->metrics.vertAdvance/64; 
        if ( use_kerning && previous && glyph_index )
        {
            FT_Vector  delta;
            FT_Get_Kerning( face, previous, glyph_index, FT_KERNING_DEFAULT, &delta );
            posx += (delta.x/64);
        }
        posx+=(dx);
        my_draw_bitmap(img,&slot->bitmap,posx+x+ slot->bitmap_left,y - slot->bitmap_top+posy,color);
        previous = glyph_index;
    }
    return prev_yadv;
}
//-----------------------------------------------------------------------
void PrintText(Mat& img,std::wstring str,int x,int y,Scalar color)
{
    float posy=0;
    for(int pos=str.find_first_of(L'\n');pos!=wstring::npos;pos=str.find_first_of(L'\n'))
    {
        std::wstring substr=str.substr(0,pos);
        str.erase(0,pos+1);
        posy+=PrintString(img,substr,x,y+posy, color);
    }
    PrintString(img,str,x,y+posy,color);
}
//-----------------------------------------------------------------------
int main(int argc, char* argv[])
{
    FT_Init_FreeType( &library );
    FT_New_Face( library,"arial.ttf",0,&face );
    FT_Set_Pixel_Sizes(face,24,0);
    FT_Select_Charmap(face, FT_ENCODING_UNICODE);
    Mat img=imread("D:/ImagesForTest/lena.jpg");

    std::wstring str= L"Мой дядя самых честных правил,\n\
Когда не в шутку занемог,\n\
Он уважать себя заставил \n\
И лучше выдумать не мог.\n\
Его пример другим наука;\n\
Но, боже мой, какая скука\n\
С больным сидеть и день и ночь,\n\
Не отходя ни шагу прочь!\n\
Какое низкое коварство\n\
Полу-живого забавлять,\n\
Ему подушки поправлять,\n\
Печально подносить лекарство,\n\
Вздыхать и думать про себя:\n\
Когда же чёрт возьмет тебя!\n";

    PrintText(img,str,100,50,Scalar(0,255,255));
    cv::imshow("win",img);
    cv::waitKey(0);
    return 0;
}
#包括“opencv2/opencv.hpp”
#包括“ft2build.h”
#包括FT_FREETYPE_H
英国电信大学图书馆;
面部;
使用名称空间cv;
使用名称空间std;
//-----------------------------------------------------------------------
作废我的绘图位图(Mat&img、FT\U位图*位图、整数x、整数y、标量颜色)
{
标量src_col,dst_col;
for(int i=0;irows;i++)
{
for(int j=0;jwidth;j++)
{
无符号字符值=位图->缓冲区[j+i*位图->基音];
浮动混合=(浮动)val/255.0;
如果(val!=0)
{
src_col=标量(在(i+y,j+x)处的img);
dst_-col=mix*color+(1.0-mix)*src_-col;
在(i+y,j+x)处的img.at=Vec3b(dst_col[0],dst_col[1],dst_col[2]);
}
}      
}
}
//-----------------------------------------------------------------------
浮点打印字符串(Mat&img、std::wstring str、int x、int y、标量颜色)
{
FT\u Bool use\u kerning=0;
FT_UInt previous=0;
use_kerning=FT_有_kerning(面);
浮动上一个yadv=0;
浮点posx=0;
浮点posy=0;
浮点数dx=0;
for(int k=0;kglyph;//一个小快捷方式
如果(k>0){dx=slot->advance.x/64;}
FT_加载图示符(面、图示符索引、FT_加载图示符默认值);
FT_渲染_图示符(槽、FT_渲染_模式_法线);
prev_yadv=slot->metrics.vertAdvance/64;
如果(使用紧排和上一个和字形索引)
{
向量增量;
FT_获取紧排(面、上一个、字形索引、FT_紧排默认值和增量);
posx+=(δx/64);
}
posx+=(dx);
我的绘图位图(img,&slot->bitmap,posx+x+slot->bitmap\u left,y-slot->bitmap\u top+posy,color);
先前=字形索引;
}
返回上一个yadv;
}
//-----------------------------------------------------------------------
无效打印文本(Mat&img、std::wstring str、int x、int y、标量颜色)
{
浮点posy=0;
对于(int pos=str.find_first_of(L'\n');pos!=wstring::npos;pos=str.find_first_of(L'\n'))
{
std::wstring substr=str.substr(0,位置);
str.erase(0,pos+1);
posy+=PrintString(img,substr,x,y+posy,color);
}
打印字符串(img、str、x、y+posy、颜色);
}
//-----------------------------------------------------------------------
int main(int argc,char*argv[])
{
FT_Init_FreeType(&library);
FT_New_Face(库,“arial.ttf”、0和Face);
FT_设置_像素_大小(面,24,0);
FT_选择字符映射(面,FT_编码_UNICODE);
Mat img=imread(“D:/ImagesForTest/lena.jpg”);
std::wstring str=L“Мчааааааааааааа\
зззззззз\
öажжззааа\
Пчччччччччччччччаа\
аГБПииаааааа\
ажжаа,аааааа\
Сбббббббч\
ччччччч!\n\
аазааазааазааааа\
Пбжзбзбббб\
аааааааааааа\
Пчааааааааа\
Б\
чжчёззззб!\n”;
打印文本(img,str,100,50,标量(0255255));
cv::imshow(“赢”,img);
cv::waitKey(0);
返回0;
}

推出你自己的位图文本引擎。游戏开发人员已经做了几十年了。所以我希望能从这几十年的工作中获益,而不是自己重新发明轮子。