[英]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.