Communication between PCs and font reading and display of dot matrix Chinese characters

Connection settings

Two usb ports
G-G,3.3-3.3,TX-RX,RX-TX
Open the serial port assistant to select the file and set the baud rate 1152900
Check accept data to file to view the directory where the file is saved, and then open it after transmission

Accepted


The higher the baud rate set for file transfer, the shorter the time to transfer files
Later, open the file named dat. Since the extended name is DAT, we need to modify it to the corresponding format to open it. The picture is jpg. Usually in the serial assistant folder.
Modify file extension

Open the control panel and click Tools and folder options

Click view, check hide known folder and extension name, and click apply to folder

Click rename later. You can change DAT format to jpg format

It's done

Reading and printing of dot matrix Chinese characters

1. What is a lattice?
In the previous method, one IO port can only control one led. What if we need to use fewer IO ports to control more LEDs? So, there is a dot matrix.
For example, the 8X8 dot matrix is composed of 64 light-emitting diodes, and each light-emitting diode is placed at the intersection of row line and column line. When a corresponding row is set to 1 level and a column is set to 0 level, the corresponding diode will be on; If the first point is to be lit, pin 1 is connected to high level and pin a is connected to low level, then the first point is lit.
2. Location code
In fact, the dot matrix font library stores the font information of Chinese characters according to the internal code order of Chinese characters. sixteen × The dot matrix font of 16 has 94 areas, and each area has 94 Chinese character fonts. There are 94 in total × 94 Chinese characters.
Internal code
The internal code of Chinese characters refers to the code that represents a Chinese character in the computer. The internal code is slightly different from the location code.

3. The area code and bit code of Chinese location code are between 1-94. If the location code is directly used as the internal code, it will be confused with the basic ASCII code. In order to avoid the conflict between the internal code and the basic ASCII code, it is necessary to avoid the control code (00H~1FH) in the basic ASCII code and distinguish it from the characters in the basic ASCII code.
Therefore, 20H is added to the area code and bit code respectively, and 80H is added on this basis.

After these processes, it takes two bytes to represent a Chinese character with internal code, which are called high byte and low byte respectively. The internal code of these two bytes is represented according to the following rules:
High byte = Area code + 20H + 80H(Or area code + A0H)
Low byte = Bit code + 20H + 80H(Or bit code + AOH)

4. Acquiring Chinese characters by using Chinese character internal code
The relationship between location code and internal code of Chinese characters is as follows:

High byte of internal code = area code + 20h + 80h (or area code + A0H)
Low byte of internal code = bit code + 20h + 80h (or bit code + AOH)
Conversely, we can also obtain the location code according to the internal code:

Area code = High bit of internal code - A0H
 Bit code = Low byte of internal code - AOH
 In this way, after calculating the location code, we can use it to address and find the font in the Chinese character library. Specific method:
The offset address of the Chinese character =(Area code-1)×94×The number of bytes occupied by a word + Bit code×The number of bytes occupied by a word

Under ubuntu, call opencv with c to display text and pictures

Create text file
A picture to be displayed, 24 * 24 dot matrix. hz file, ASCII code. zf file, and text file to be displayed
(Note: when inputting the text you want to display in the logo.txt file, it needs to be written in ANSI code, otherwise Chinese will be garbled)
Create a text document and save it in ANSI format

ANSI Usually use 0 x80~0xFF 2 bytes of the range to represent 1 character. Unicode The characters are arranged in 17 groups,   UTF-8 Encoded in 1 to 6 bytes UNICODE Character.
ANSI Is a character code. In order to make the computer support more languages, 0 is usually used x80~0xFF 2 bytes of the range to represent 1 character. One byte for English characters and two or four bytes for Chinese characters.
UTF-8(8-bit Unicode Transformation Format)Is a kind of Unicode Variable length character coding, also known as universal code. from Ken Thompson Founded in 1992. Now it has been standardized into RFC 3629. 

Open the virtual machine and put the Chinese character library, text files, pictures and ASC in the opencv folder of ubuntu,

Open the terminal and navigate to the opencv folder

Create text files and edit c/c + + language

#include<iostream>
#include<opencv/cv.h>
#include"opencv2/opencv.hpp"
#include<opencv/cxcore.h>
#include<opencv/highgui.h>
#include<math.h>

using namespace cv;
using namespace std;

void paint_chinese(Mat& image,int x_offset,int y_offset,unsigned long offset);
void paint_ascii(Mat& image,int x_offset,int y_offset,unsigned long offset);
void put_text_to_image(int x_offset,int y_offset,String image_path,char* logo_path);

int main(){
    String image_path="2.jpg";//Name of picture
    char* logo_path="logo.txt";//Name of Chinese character file
    put_text_to_image(700,800,image_path,logo_path);//change txt place
    return 0;
}

void paint_ascii(Mat& image,int x_offset,int y_offset,unsigned long offset){
    //Coordinates of the starting point of the drawing
	Point p;
	p.x = x_offset;
	p.y = y_offset;
	 //Storing ascii word film
	char buff[16];           
	//Open ascii font file
	FILE *ASCII;

	if ((ASCII = fopen("Asci0816.zf", "rb")) == NULL){
		printf("Can't open ascii.zf,Please check the path!");
		//getch();
		exit(0);
	}

	fseek(ASCII, offset, SEEK_SET);
	fread(buff, 16, 1, ASCII);

	int i, j;
	Point p1 = p;
	for (i = 0; i<16; i++)                  //Sixteen char s
	{
		p.x = x_offset;
		for (j = 0; j < 8; j++)              //One char and eight bit s
		{
			p1 = p;
			if (buff[i] & (0x80 >> j))    /*Test whether the current bit is 1*/
			{
				/*
					Because the original ascii word film was 8 * 16, it was not large enough,
					So the original pixel is replaced by four pixels,
					After replacement, there are 16 * 32 pixels
					ps: I think it's unnecessary to write code like this, but I only think of this method for the time being
				*/
				circle(image, p1, 0, Scalar(0, 0, 255), -1);
				p1.x++;
				circle(image, p1, 0, Scalar(0, 0, 255), -1);
				p1.y++;
				circle(image, p1, 0, Scalar(0, 0, 255), -1);
				p1.x--;
			   circle(image, p1, 0, Scalar(0, 0, 255), -1);
			}						
            p.x+=2;            //One pixel becomes four, so x and y should both be + 2
		}
		p.y+=2;
	}
}
void paint_chinese(Mat& image,int x_offset,int y_offset,unsigned long offset){//Draw Chinese characters on the picture
    Point p;
    p.x=x_offset;
    p.y=y_offset;
    FILE *HZK;
    char buff[72];//72 bytes for storing Chinese characters

    if((HZK=fopen("HZKf2424.hz","rb"))==NULL){
        printf("Can't open HZKf2424.hz,Please check the path!");
        exit(0);//sign out
    }
    fseek(HZK, offset, SEEK_SET);/*Move the file pointer to the offset position*/
    fread(buff, 72, 1, HZK);/*Read 72 bytes from the offset position, and each Chinese character occupies 72 bytes*/
    bool mat[24][24];//Define a new matrix to store the transposed text film
    int i,j,k;
    for (i = 0; i<24; i++)                 /*24x24 Dot matrix Chinese characters, a total of 24 lines*/
	{
        	for (j = 0; j<3; j++)                /*There are 3 bytes in the horizontal direction, and the value of each byte is determined by cycle*/
			for (k = 0; k<8; k++)              /*Each byte has 8 bits, and the loop judges whether each byte is 1*/
				if (buff[i * 3 + j] & (0x80 >> k))    /*Test whether the current bit is 1*/
				{
					mat[j * 8 + k][i] = true;          /*1 is stored in a new word film*/
				}
				else {
					mat[j * 8 + k][i] = false;
				}
	}
	
    for (i = 0; i < 24; i++)
	{
		p.x = x_offset;
		for (j = 0; j < 24; j++)
		{		
			if (mat[i][j])
				circle(image, p, 1, Scalar(255, 0, 0), -1);		  //Write (replace) pixels
			p.x++;                                                //Shift right one pixel
		}
		p.y++;                                                    //Move down one pixel
	}
}

void put_text_to_image(int x_offset,int y_offset,String image_path,char* logo_path){//Put Chinese characters on the picture
//x and y are the starting coordinates of the first word on the picture
    //Get pictures through picture path
    Mat image=imread(image_path);
    int length=16;//The length of characters to be printed (the length can be as many bytes as you print, which can be adjusted according to your own situation)
    unsigned char qh,wh;//Define area code and tag number
    unsigned long offset;//Offset
    unsigned char hexcode[30];//Hexadecimal used to store Notepad reading. Remember to use unsigned
    FILE* file_logo;

    if ((file_logo = fopen(logo_path, "rb")) == NULL){
		printf("Can't open txtfile,Please check the path!");
		//getch();
		exit(0);
	}

    fseek(file_logo, 0, SEEK_SET);
    fread(hexcode, length, 1, file_logo);
    int x =x_offset,y = y_offset;//x. Y: the starting coordinate of the text drawn on the picture

    for(int m=0;m<length;){
        if(hexcode[m]==0x23){
            break;//It ends when the # number is read
        }
        else if(hexcode[m]>0xaf){
            qh=hexcode[m]-0xaf;//The font used starts with Chinese characters, not Chinese symbols
            wh=hexcode[m+1] - 0xa0;//Calculation bit code
            offset=(94*(qh-1)+(wh-1))*72L;
            paint_chinese(image,x,y,offset);
            /*
            Calculate the offset in the Chinese character library
            Each Chinese character is represented by a 24 * 24 dot matrix
            A line has three bytes, a total of 24 lines, so 72 bytes are required
            */

            m=m+2;//The internal code of a Chinese character occupies two bytes,
            x+=24;//A Chinese character has 24 * 24 pixels. Because it is placed horizontally, it moves 24 pixels to the right
        }

        else{
        //When the read character is ASCII
        wh=hexcode[m];
        offset=wh*16l;//Calculate the offset of English characters
        paint_ascii(image,x,y,offset);
        m++;//English characters only occupy one byte in the file, so just move back one bit
        x+=16;
        }

    }

    cv::imshow("image", image);
    cv::waitKey();
}


Here, pay attention to the size of the photo, and then choose the location. Mine is 700800, and the byte length needs to be modified
A Chinese character has 2 bytes, a number has 1 byte, a space has 1 byte, and mine is 16 bytes
Then compile and run the link to check whether there is an error

shu@shu-virtual-machine:~/opencv-3.4.11$ g++ word.cpp -o word `pkg-config --cflags --libs opencv`
word.cpp: In function 'int main()':
word.cpp:17:21: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
     char* logo_path="logo.txt";//Name of Chinese character file
                     ^
shu@shu-virtual-machine:~/opencv-3.4.11$ ls
2.jpg        build            data         LICENSE    README.md
3rdparty     cmake            doc          logo.txt   samples
apps         CMakeLists.txt   HZKf2424.hz  modules    word
Asci0816.zf  CONTRIBUTING.md  include      platforms  word.cpp

The first command runs and compiles ls to see if an executable file is generated
Run the executable later

shu@shu-virtual-machine:~/opencv-3.4.11$ ./word

Operation results

summary

This experiment let me know more about the use of opencv and the use of related logo characters. Combining theory with practice, I completed the extraction of Chinese character library and the related communication of usb serial port

Keywords: OpenCV stm32

Added by John Rowe on Fri, 19 Nov 2021 14:25:59 +0200