当前位置:网站首页>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 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?
- Ueeditor internationalization configuration, supporting Chinese and English switching
- [unity] simulate jelly effect (with collision) -- tutorial on using jellysprites plug-in
- C miscellaneous two-way circular linked list
- Windchill configure remote Oracle database connection
- 软件测试工程师必备之软技能:结构化思维
- Complete web login process through filter
- 实现以form-data参数发送post请求
- MySQL的存储引擎
- Advantages and disadvantages of evaluation methods
猜你喜欢
Jar runs with error no main manifest attribute
MySQL transaction log
C miscellaneous lecture continued
Adaptive Bezier curve network for real-time end-to-end text recognition
MySQL实战优化高手02 为了执行SQL语句,你知道MySQL用了什么样的架构设计吗?
13 医疗挂号系统_【 微信登录】
South China Technology stack cnn+bilstm+attention
MySQL24-索引的数据结构
[Julia] exit notes - Serial
【C语言】深度剖析数据存储的底层原理
随机推荐
MySQL transaction log
Solution to the problem of cross domain inaccessibility of Chrome browser
数据库中间件_Mycat总结
MySQL实战优化高手11 从数据的增删改开始讲起,回顾一下Buffer Pool在数据库里的地位
MySQL实战优化高手12 Buffer Pool这个内存数据结构到底长个什么样子?
16 medical registration system_ [order by appointment]
MySQL combat optimization expert 06 production experience: how does the production environment database of Internet companies conduct performance testing?
MySQL combat optimization expert 04 uses the execution process of update statements in the InnoDB storage engine to talk about what binlog is?
如何搭建接口自动化测试框架?
MySQL31-MySQL事务日志
Water and rain condition monitoring reservoir water and rain condition online monitoring
好博客好资料记录链接
In fact, the implementation of current limiting is not complicated
基于Pytorch肺部感染识别案例(采用ResNet网络结构)
Nanny hand-in-hand teaches you to write Gobang in C language
Good blog good material record link
Installation of pagoda and deployment of flask project
C miscellaneous lecture continued
软件测试工程师必备之软技能:结构化思维
[after reading the series of must know] one of how to realize app automation without programming (preparation)