簡體   English   中英

如何將freetype位圖緩沖區正確轉換為opencv Mat?

[英]How to properly convert a freetype bitmap buffer to opencv Mat?

我正在嘗試將 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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM