gpt4 book ai didi

c++ - 如何正确地将freetype位图缓冲区转换为opencv Mat?

转载 作者:行者123 更新时间:2023-12-02 10:36:50 24 4
gpt4 key购买 nike

我正在尝试将freetype位图缓冲区转换为cv::Mat。到目前为止,这就是我所得到的(我仅将代码的相关部分放到了一起)

struct glyph_t
{
uchar character;
cv::Mat mat;
b2PolygonShape shape;
unsigned char* bitmap_buffer;
};

// ...

// Initialize freetype library
if (FT_Init_FreeType(&m_library))
// ... error handling here

if (FT_New_Face(m_library, R"(C:\Windows\Fonts\Arial.ttf)", 0, &m_face))
// ... error handling here

FT_Set_Pixel_Sizes(m_face, 0, 48);

// ...

// only capital letters
for (auto c = 65; c <= 90; c++)
{
if (FT_Load_Char(m_face, c, FT_LOAD_RENDER))
// ... error handling here

glyph_t g;

g.bitmap_buffer = m_face->glyph->bitmap.buffer;
g.character = c;
g.mat = cv::Mat(
m_face->glyph->bitmap.rows,
m_face->glyph->bitmap.width,
CV_8UC1,
m_face->glyph->bitmap.buffer);

m_glyphs.push_back(g); // std::vector<glyph_t>
}

如果我现在输出带有 <<重载的Mat,如下所示:
for (auto m_glyph : m_glyphs)
{
std::cout << m_glyph.mat << std::endl;
std::cout << static_cast<uint>(m_glyph.bitmap_buffer[0]) << std::endl;
}

例如,字母 L的输出如下所示。对于字母 A,Mat仅包含221 ...的值,因此我将位图缓冲区转换为 cv::Mat的方式一定存在问题。我在这里做错了什么?

请注意:我添加了第二个输出以进行快速检查,因此我可以比较数组的第一个值是否与Mat的第一个匹配
[  0,   0,  12, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 144,   0;
0, 0, 12, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 144, 0;
0, 0, 12, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 144, 0;
0, 0, 12, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 144, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 253, 255, 255, 255, 247, 51, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 248, 255, 255, 255, 255, 97, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 237, 255, 255, 255, 255, 152, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 210, 255, 255, 255, 255, 200, 6, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 170, 255, 255, 255, 255, 233, 28, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114, 255, 255, 255, 255, 251, 64, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 251, 255, 255, 255, 255, 114, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 231, 255, 255, 255, 255, 169, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 194, 255, 255, 255, 255, 212, 11, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142, 255, 255, 255, 255, 241, 37, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 255, 255, 255, 255, 254, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 243, 255, 255, 255, 255, 132, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 214, 255, 255, 255, 255, 184, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 169, 255, 255, 255, 255, 223, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 112, 255, 255, 255, 255, 246, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 251, 255, 255, 255, 255, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 23, 230, 255, 255, 255, 255, 149, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 4, 193, 255, 255, 255, 255, 198, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 140, 255, 255, 255, 255, 232, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 83, 255, 255, 255, 255, 251, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 39, 242, 255, 255, 255, 255, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 11, 213, 255, 255, 255, 255, 166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 167, 255, 255, 255, 255, 210, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 111, 255, 255, 255, 255, 240, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 59, 250, 255, 255, 255, 253, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 23, 229, 255, 255, 255, 255, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
1, 192, 255, 255, 255, 255, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
8, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 32;
8, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 32;
8, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 32;
8, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 32]
0

编辑

当像这样手动填充垫子时,它可以工作...所以我创建垫子的方式一定有问题...
cv::Mat m = cv::Mat(m_face->glyph->bitmap.rows, m_face->glyph->bitmap.width, CV_8UC1);

for (uint row = 0; row < m_face->glyph->bitmap.rows; row++)
{
for (uint i = 0; i < m_face->glyph->bitmap.width; i++)
{
auto value = m_face->glyph->bitmap.buffer[row*m_face->glyph->bitmap.width+i];
m.at<uchar>(row, i) = value;
}
}

最佳答案

我想到了。 OpenCV拥有自己的内存管理和引用计数机制。这意味着只要cv::Mat对象超出范围,它的内存就会被释放。

因此,我构造对象的方式没有任何问题。但是我在分配之前忘记了克隆。

glyph_t g;

g.bitmap_buffer = m_face->glyph->bitmap.buffer;
g.character = c;

cv::Mat m(
m_face->glyph->bitmap.rows,
m_face->glyph->bitmap.width,
CV_8UC1,
m_face->glyph->bitmap.buffer);

g.mat = m.clone(); // This made the trick...
m_glyphs.push_back(g);

关于c++ - 如何正确地将freetype位图缓冲区转换为opencv Mat?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59887237/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com