当前位置:网站首页>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;
}
边栏推荐
- Google login prompt error code 12501
- 14 医疗挂号系统_【阿里云OSS、用户认证与就诊人】
- Several errors encountered when installing opencv
- MySQL实战优化高手05 生产经验:真实生产环境下的数据库机器配置如何规划?
- 好博客好资料记录链接
- MySQL Real Time Optimization Master 04 discute de ce qu'est binlog en mettant à jour le processus d'exécution des déclarations dans le moteur de stockage InnoDB.
- [programmers' English growth path] English learning serial one (verb general tense)
- 13 医疗挂号系统_【 微信登录】
- 百度百科数据爬取及内容分类识别
- Use xtrabackup for MySQL database physical backup
猜你喜欢
How to find the number of daffodils with simple and rough methods in C language
MySQL combat optimization expert 02 in order to execute SQL statements, do you know what kind of architectural design MySQL uses?
[Julia] exit notes - Serial
MySQL27-索引優化與查詢優化
Export virtual machines from esxi 6.7 using OVF tool
MySQL实战优化高手03 用一次数据更新流程,初步了解InnoDB存储引擎的架构设计
What should the redis cluster solution do? What are the plans?
Not registered via @enableconfigurationproperties, marked (@configurationproperties use)
MySQL30-事务基础知识
Security design verification of API interface: ticket, signature, timestamp
随机推荐
Export virtual machines from esxi 6.7 using OVF tool
Southwest University: Hu hang - Analysis on learning behavior and learning effect
Mysql27 - Optimisation des index et des requêtes
C miscellaneous shallow copy and deep copy
Anaconda3 installation CV2
Windchill configure remote Oracle database connection
UEditor国际化配置,支持中英文切换
Time in TCP state_ The role of wait?
How to change php INI file supports PDO abstraction layer
MySQL combat optimization expert 09 production experience: how to deploy a monitoring system for a database in a production environment?
MySQL combat optimization expert 03 uses a data update process to preliminarily understand the architecture design of InnoDB storage engine
[after reading the series] how to realize app automation without programming (automatically start Kwai APP)
C miscellaneous dynamic linked list operation
How to build an interface automation testing framework?
用于实时端到端文本识别的自适应Bezier曲线网络
text 文本数据增强方法 data argumentation
C miscellaneous lecture continued
Pytoch LSTM implementation process (visual version)
MySQL real battle optimization expert 11 starts with the addition, deletion and modification of data. Review the status of buffer pool in the database
MySQL实战优化高手08 生产经验:在数据库的压测过程中,如何360度无死角观察机器性能?