当前位置:网站首页>Opencv uses freetype to display Chinese
Opencv uses freetype to display Chinese
2022-07-06 10:34:00 【Orange @c】
because Opencv Chinese is not displayed by default , So we need some libraries to set OpenCV Support Chinese display
Code instructions
Project needs ft2build.h, It is freetype A header file in the Library . So in shell Execute the following statement to install freetype:
sudo apt-get install libfreetype6-dev
Then use the following statement to find ft2build.h And in cmake Just link in
sudo find / -name ft2build.h
test freetype Can you use
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#define WIDTH 80
#define HEIGHT 80
/* origin is the upper left corner */
unsigned char image[HEIGHT][WIDTH];
/* Replace this function with something useful. */
void
draw_bitmap( FT_Bitmap* bitmap,
FT_Int x,
FT_Int y)
{
FT_Int i, j, p, q;
FT_Int x_max = x + bitmap->width;
FT_Int y_max = y + bitmap->rows;
for ( i = x, p = 0; i < x_max; i++, p++ )
{
for ( j = y, q = 0; j < y_max; j++, q++ )
{
if ( i < 0 || j < 0 ||
i >= WIDTH || j >= HEIGHT )
continue;
image[j][i] |= bitmap->buffer[q * bitmap->width + p];
}
}
}
void
show_image( void )
{
int i, j;
for ( i = 0; i < HEIGHT; i++ )
{
for ( j = 0; j < WIDTH; j++ )
putchar( image[i][j] == 0 ? ' '
: image[i][j] < 128 ? '+'
: '*' );
putchar( '\n' );
}
}
int
main( int argc,
char** argv )
{
FT_Library library;
FT_Face face;
FT_GlyphSlot slot;
FT_Matrix matrix; /* transformation matrix */
FT_Vector pen; /* untransformed origin */
FT_Error error;
char* filename;
char* text;
double angle;
int target_height;
int n, num_chars;
if ( argc != 3 )
{
fprintf ( stderr, "usage: %s font sample-text\n", argv[0] );
exit( 1 );
}
filename = argv[1]; /* first argument */
text = argv[2]; /* second argument */
num_chars = strlen( text );
angle = ( 0.0 / 360 ) * 3.14159 * 2; /* use 25 degrees */
target_height = HEIGHT;
error = FT_Init_FreeType( &library ); /* initialize library */
/* error handling omitted */
error = FT_New_Face( library, argv[1], 0, &face ); /* create face object */
/* error handling omitted */
#if 0
/* use 50pt at 100dpi */
error = FT_Set_Char_Size( face, 50 * 64, 0,
100, 0 ); /* set character size */
/* pixels = 50 /72 * 100 = 69 */
#else
FT_Set_Pixel_Sizes(face, 24, 0);
#endif
/* error handling omitted */
slot = face->glyph;
/* set up matrix */
matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L );
matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L );
matrix.yx = (FT_Fixed)( sin( angle ) * 0x10000L );
matrix.yy = (FT_Fixed)( cos( angle ) * 0x10000L );
/* the pen position in 26.6 cartesian space coordinates; */
/* start at (0,40) relative to the upper left corner */
pen.x = 0 * 64;
pen.y = ( target_height - 40 ) * 64;
for ( n = 0; n < num_chars; n++ )
{
/* set transformation */
FT_Set_Transform( face, &matrix, &pen );
/* load glyph image into the slot (erase previous one) */
error = FT_Load_Char( face, text[n], FT_LOAD_RENDER );
if ( error )
continue; /* ignore errors */
/* now, draw to our target surface (convert position) */
draw_bitmap( &slot->bitmap,
slot->bitmap_left,
target_height - slot->bitmap_top );
/* increment pen position */
pen.x += slot->advance.x;
pen.y += slot->advance.y;
}
show_image();
FT_Done_Face ( face );
FT_Done_FreeType( library );
return 0;
}
gcc -o test test.cpp -I/usr/include/freetype2/ -lfreetype -lm
./test ./simhei.ttf hello
- simhei.ttf Is a font file , Can be in windows The system indexes directly , Just change your favorite default font .
cmake file
cmake_minimum_required(VERSION 3.12)
project(chinese)
set(CMAKE_CXX_STANDARD 14)
find_package(OpenCV REQUIRED)
message(STATUS ${OpenCV_LIBRARY_DIRS})
include_directories(
/usr/include/freetype2/
${OpenCV_INCLUDE_DIRS}
)
#link_directories(${OpenCV_LIBRARY_DIRS} )
add_executable(chinese main.cpp CvxText.cpp CvxText.h)
target_link_libraries(chinese ${OpenCV_LIBS} freetype)
CvxText.h
#ifndef OPENCV_CVX_TEXT_HPP_
#define OPENCV_CVX_TEXT_HPP_
// source from: http://www.opencv.org.cn/forum.php?mod=viewthread&tid=2083&extra=&page=1
// Support OpenCV Chinese character input
#include <ft2build.h>
#include FT_FREETYPE_H
#include <opencv2/opencv.hpp>
class CvxText {
public:
/**
* Load font file
*/
CvxText(const char* freeType);
virtual ~CvxText();
/**
* Get the font . At present, some parameters do not support .
*
* \param font Font type , Currently not supported
* \param size font size / Blank scale / Interval ratio / Rotation Angle
* \param underline Draw the line down
* \param diaphaneity transparency
*
* \sa setFont, restoreFont
*/
void getFont(int* type, cv::Scalar* size=nullptr, bool* underline=nullptr, float* diaphaneity=nullptr);
/**
* Set the font . At present, some parameters do not support .
*
* \param font Font type , Currently not supported
* \param size font size / Blank scale / Interval ratio / Rotation Angle
* \param underline Draw the line down
* \param diaphaneity transparency
*
* \sa getFont, restoreFont
*/
void setFont(int* type, cv::Scalar* size=nullptr, bool* underline=nullptr, float* diaphaneity=nullptr);
/**
* Restore the original font settings .
*
* \sa getFont, setFont
*/
void restoreFont();
/**
* Output Chinese characters ( The default color is black ). If you encounter characters that cannot be output, you will stop .
*
* \param img Output image
* \param text Text content
* \param pos Text location
*
* \return Returns the length of characters successfully output , Failure to return -1.
*/
int putText(cv::Mat& img, char* text, cv::Point pos);
/**
* Output Chinese characters ( The default color is black ). If you encounter characters that cannot be output, you will stop .
*
* \param img Output image
* \param text Text content
* \param pos Text location
*
* \return Returns the length of characters successfully output , Failure to return -1.
*/
int putText(cv::Mat& img, const wchar_t* text, cv::Point pos);
/**
* Output Chinese characters . If you encounter characters that cannot be output, you will stop .
*
* \param img Output image
* \param text Text content
* \param pos Text location
* \param color text color
*
* \return Returns the length of characters successfully output , Failure to return -1.
*/
int putText(cv::Mat& img, const char* text, cv::Point pos, cv::Scalar color);
/**
* Output Chinese characters . If you encounter characters that cannot be output, you will stop .
*
* \param img Output image
* \param text Text content
* \param pos Text location
* \param color text color
*
* \return Returns the length of characters successfully output , Failure to return -1.
*/
int putText(cv::Mat& img, const wchar_t* text, cv::Point pos, cv::Scalar color);
private:
// prohibit copy
CvxText& operator=(const CvxText&);
// Output the current character , to update m_pos Location
void putWChar(cv::Mat& img, wchar_t wc, cv::Point& pos, cv::Scalar color);
FT_Library m_library; // Word stock
FT_Face m_face; // typeface
// Default font output parameters
int m_fontType;
cv::Scalar m_fontSize;
bool m_fontUnderline;
float m_fontDiaphaneity;
};
#endif // OPENCV_CVX_TEXT_HPP_
CvxText.cpp
#include <wchar.h>
#include <assert.h>
#include <locale.h>
#include <ctype.h>
#include <cmath>
#include "CvxText.h"
// Open the font
CvxText::CvxText(const char* freeType)
{
assert(freeType != NULL);
// Open the font file , Create a font
if(FT_Init_FreeType(&m_library)) throw;
if(FT_New_Face(m_library, freeType, 0, &m_face)) throw;
// Set font output parameters
restoreFont();
// Set up C Language character set environment
setlocale(LC_ALL, "");
}
// Release FreeType resources
CvxText::~CvxText()
{
FT_Done_Face(m_face);
FT_Done_FreeType(m_library);
}
// Set font parameters :
//
// font - Font type , Currently not supported
// size - font size / Blank scale / Interval ratio / Rotation Angle
// underline - Draw the line down
// diaphaneity - transparency
void CvxText::getFont(int* type, cv::Scalar* size, bool* underline, float* diaphaneity)
{
if (type) *type = m_fontType;
if (size) *size = m_fontSize;
if (underline) *underline = m_fontUnderline;
if (diaphaneity) *diaphaneity = m_fontDiaphaneity;
}
void CvxText::setFont(int* type, cv::Scalar* size, bool* underline, float* diaphaneity)
{
// Parameter validity check
if (type) {
if(type >= 0) m_fontType = *type;
}
if (size) {
m_fontSize.val[0] = std::fabs(size->val[0]);
m_fontSize.val[1] = std::fabs(size->val[1]);
m_fontSize.val[2] = std::fabs(size->val[2]);
m_fontSize.val[3] = std::fabs(size->val[3]);
}
if (underline) {
m_fontUnderline = *underline;
}
if (diaphaneity) {
m_fontDiaphaneity = *diaphaneity;
}
FT_Set_Pixel_Sizes(m_face, (int)m_fontSize.val[0], 0);
}
// Restore the original font settings
void CvxText::restoreFont()
{
m_fontType = 0; // Font type ( I won't support it )
m_fontSize.val[0] = 20; // font size
m_fontSize.val[1] = 0.5; // White space character size ratio
m_fontSize.val[2] = 0.1; // Interval size ratio
m_fontSize.val[3] = 0; // Rotation Angle ( I won't support it )
m_fontUnderline = false; // Draw the line down ( I won't support it )
m_fontDiaphaneity = 1.0; // Color ratio ( Can produce a transparent effect )
// Set character size
FT_Set_Pixel_Sizes(m_face, (int)m_fontSize.val[0], 0);
}
// Output function ( The default color is white )
int CvxText::putText(cv::Mat& img, char* text, cv::Point pos)
{
return putText(img, text, pos, CV_RGB(255, 255, 255));
}
int CvxText::putText(cv::Mat& img, const wchar_t* text, cv::Point pos)
{
return putText(img, text, pos, CV_RGB(255,255,255));
}
int CvxText::putText(cv::Mat& img, const char* text, cv::Point pos, cv::Scalar color)
{
if (img.data == nullptr) return -1;
if (text == nullptr) return -1;
int i;
for (i = 0; text[i] != '\0'; ++i) {
wchar_t wc = text[i];
// Parsing double byte symbols
if(!isascii(wc)) mbtowc(&wc, &text[i++], 2);
// Output the current character
putWChar(img, wc, pos, color);
}
return i;
}
int CvxText::putText(cv::Mat& img, const wchar_t* text, cv::Point pos, cv::Scalar color)
{
if (img.data == nullptr) return -1;
if (text == nullptr) return -1;
int i;
for(i = 0; text[i] != '\0'; ++i) {
// Output the current character
putWChar(img, text[i], pos, color);
}
return i;
}
// Output the current character , to update m_pos Location
void CvxText::putWChar(cv::Mat& img, wchar_t wc, cv::Point& pos, cv::Scalar color)
{
// according to unicode Generate binary bitmap of font
FT_UInt glyph_index = FT_Get_Char_Index(m_face, wc);
FT_Load_Glyph(m_face, glyph_index, FT_LOAD_DEFAULT);
FT_Render_Glyph(m_face->glyph, FT_RENDER_MODE_MONO);
FT_GlyphSlot slot = m_face->glyph;
// Number of rows and columns
int rows = slot->bitmap.rows;
int cols = slot->bitmap.width;
for (int i = 0; i < rows; ++i) {
for(int j = 0; j < cols; ++j) {
int off = i * slot->bitmap.pitch + j/8;
if (slot->bitmap.buffer[off] & (0xC0 >> (j%8))) {
int r = pos.y - (rows-1-i);
int c = pos.x + j;
if(r >= 0 && r < img.rows && c >= 0 && c < img.cols) {
cv::Vec3b pixel = img.at<cv::Vec3b>(cv::Point(c, r));
cv::Scalar scalar = cv::Scalar(pixel.val[0], pixel.val[1], pixel.val[2]);
// Color fusion
float p = m_fontDiaphaneity;
for (int k = 0; k < 4; ++k) {
scalar.val[k] = scalar.val[k]*(1-p) + color.val[k]*p;
}
img.at<cv::Vec3b>(cv::Point(c, r))[0] = (unsigned char)(scalar.val[0]);
img.at<cv::Vec3b>(cv::Point(c, r))[1] = (unsigned char)(scalar.val[1]);
img.at<cv::Vec3b>(cv::Point(c, r))[2] = (unsigned char)(scalar.val[2]);
}
}
}
}
// Modify the output position of the next word
double space = m_fontSize.val[0]*m_fontSize.val[1];
double sep = m_fontSize.val[0]*m_fontSize.val[2];
pos.x += (int)((cols? cols: space) + sep);
}
main.cpp
#include <iostream>
#include <fstream>
#include <stdlib.h>
//#include <io.h>
#include <string>
#include <vector>
#include "opencv2/opencv.hpp"
#include "time.h"
#include "CvxText.h"
static int ToWchar(char* &src, wchar_t* &dest, const char *locale = "zh_CN.utf8")
{
if (src == NULL) {
dest = NULL;
return 0;
}
// Set according to the environment variable locale
setlocale(LC_CTYPE, locale);
// Get the required wide character size
int w_size = mbstowcs(NULL, src, 0) + 1;
// w_size = 0 explain mbstowcs The return value is -1. That is, illegal characters are encountered during operation ( It is likely to make locale
// Not set correctly )
if (w_size == 0) {
dest = NULL;
return -1;
}
//wcout << "w_size" << w_size << endl;
dest = new wchar_t[w_size];
if (!dest) {
return -1;
}
int ret = mbstowcs(dest, src, strlen(src)+1);
if (ret <= 0) {
return -1;
}
return 0;
}
int main()
{
cv::Mat img = cv::imread("./demo.jpg");
if (!img.data || img.channels() != 3) {
fprintf(stderr, "read image fail\n");
return -1;
}
CvxText text("./simhei.ttf"); // Specified font
cv::Scalar size1{ 80, 0.5, 0.1, 0 }; // ( font size , invalid , Between characters , invalid }
text.setFont(nullptr, &size1, nullptr, 0);
char* str = (char *)" Hello , Li Jiawang ";
wchar_t *w_str;
ToWchar(str,w_str);
text.putText(img, w_str, cv::Point(50,100), cv::Scalar(0, 0, 255));
cv::resize(img, img, cv::Size(300,300));
cv::imshow("demo", img);
cv::waitKey(0);
cv::imwrite("./res.jpg", img);
return 0;
}
边栏推荐
- MySQL combat optimization expert 06 production experience: how does the production environment database of Internet companies conduct performance testing?
- 第一篇博客
- Mysql32 lock
- Emotional classification of 1.6 million comments on LSTM based on pytoch
- Mysql33 multi version concurrency control
- MySQL combat optimization expert 09 production experience: how to deploy a monitoring system for a database in a production environment?
- 在jupyter NoteBook使用Pytorch进行MNIST实现
- 数据库中间件_Mycat总结
- Mysql27 index optimization and query optimization
- Sed text processing
猜你喜欢
MySQL实战优化高手03 用一次数据更新流程,初步了解InnoDB存储引擎的架构设计
该不会还有人不懂用C语言写扫雷游戏吧
Installation of pagoda and deployment of flask project
MySQL25-索引的创建与设计原则
MySQL实战优化高手04 借着更新语句在InnoDB存储引擎中的执行流程,聊聊binlog是什么?
[after reading the series] how to realize app automation without programming (automatically start Kwai APP)
Record the first JDBC
MySQL27-索引優化與查詢優化
Preliminary introduction to C miscellaneous lecture document
Unicode decodeerror: 'UTF-8' codec can't decode byte 0xd0 in position 0 successfully resolved
随机推荐
MySQL real battle optimization expert 08 production experience: how to observe the machine performance 360 degrees without dead angle in the process of database pressure test?
How to make shell script executable
MySQL32-锁
Not registered via @EnableConfigurationProperties, marked(@ConfigurationProperties的使用)
MySQL24-索引的数据结构
MySQL combat optimization expert 10 production experience: how to deploy visual reporting system for database monitoring system?
Good blog good material record link
Security design verification of API interface: ticket, signature, timestamp
The governor of New Jersey signed seven bills to improve gun safety
Adaptive Bezier curve network for real-time end-to-end text recognition
C miscellaneous two-way circular linked list
Bytetrack: multi object tracking by associating every detection box paper reading notes ()
Implement sending post request with form data parameter
MySQL transaction log
Just remember Balabala
Record the first JDBC
在jupyter NoteBook使用Pytorch进行MNIST实现
Mysql30 transaction Basics
How to build an interface automation testing framework?
C miscellaneous lecture continued