Как правильно преобразовать буфер растрового изображения в opencv Mat? - PullRequest
1 голос
/ 24 января 2020

Я пытаюсь преобразовать буферы растрового изображения в 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>
}

Если я сейчас вывожу Мат с перегрузкой << следующим образом:

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 Мат содержит только значения 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;
  }
}

1 Ответ

0 голосов
/ 25 января 2020

Я понял это. 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);
...