1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-30 15:53:03 +04:00

added truetype font support into OpenCV, based on STB_truetype

This commit is contained in:
Vadim Pisarevsky
2020-11-11 22:17:05 +03:00
parent 1088d95c50
commit d42665d9e2
26 changed files with 7786 additions and 3720 deletions
+179 -2
View File
@@ -86,6 +86,9 @@ void CV_DrawingTest::run( int )
float Eps = 1;
if( err > Eps)
{
//imshow("reference", valImg);
//imshow("result", testImg);
//waitKey();
ts->printf( ts->LOG, "NORM_L1 between testImg and valImg is equal %f (larger than %f)\n", err, Eps );
ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
}
@@ -619,8 +622,17 @@ TEST(Drawing, putText_no_garbage)
EXPECT_EQ(0, cv::countNonZero(mat(Rect(0, 0, 10, sz.height))));
EXPECT_EQ(0, cv::countNonZero(mat(Rect(sz.width-10, 0, 10, sz.height))));
EXPECT_EQ(0, cv::countNonZero(mat(Rect(205, 0, 10, sz.height))));
EXPECT_EQ(0, cv::countNonZero(mat(Rect(405, 0, 10, sz.height))));
EXPECT_EQ(0, cv::countNonZero(mat(Rect(190, 0, 10, sz.height))));
EXPECT_EQ(0, cv::countNonZero(mat(Rect(380, 0, 10, sz.height))));
#if 0
rectangle(mat, Rect(0, 0, 10, sz.height), Scalar::all(255), 1, LINE_8);
rectangle(mat, Rect(sz.width-10, 0, 10, sz.height), Scalar::all(255), 1, LINE_8);
rectangle(mat, Rect(190, 0, 10, sz.height), Scalar::all(255), 1, LINE_8);
rectangle(mat, Rect(380, 0, 10, sz.height), Scalar::all(255), 1, LINE_8);
imshow("result", mat);
waitKey();
#endif
}
@@ -679,4 +691,169 @@ TEST(Drawing, fillpoly_circle)
EXPECT_LT(diff_fp3, 1.);
}
TEST(Drawing, fromJava_getTextSize)
{
String text = "Android all the way";
double fontScale = 2;
int thickness = 3;
int baseLine = 0;
Size res0 = getTextSize(text, FONT_HERSHEY_SCRIPT_SIMPLEX, fontScale, thickness, 0);
Size res = getTextSize(text, FONT_HERSHEY_SCRIPT_SIMPLEX, fontScale, thickness, &baseLine);
#if 0
Mat img(200, 700, CV_8UC3, Scalar::all(255));
Point org(100, 100);
putText(img, text, org, FONT_HERSHEY_SCRIPT_SIMPLEX, fontScale, Scalar(128, 0, 0), thickness);
rectangle(img, org, Point(org.x + res0.width, org.y - res0.height), Scalar(0, 0, 128), 2, LINE_AA);
imshow("result", img);
waitKey();
#endif
EXPECT_EQ(res0.width, res.width);
EXPECT_EQ(res0.height, res.height);
EXPECT_NEAR(494, res.width, 3.0);
EXPECT_NEAR(51, res.height, 3.0);
EXPECT_NEAR(10, baseLine, 3.0);
}
TEST(Drawing, fromJava_testPutTextMatStringPointIntDoubleScalarIntIntBoolean)
{
String text = "Hello World";
Size labelSize(170, 23);
Mat img(20 + (int)labelSize.height, 20 + (int)labelSize.width, CV_8U, Scalar::all(0));
Point origin(10, 10);
putText(img, text, origin, FONT_HERSHEY_SIMPLEX, 1.0, Scalar::all(255), 1, LINE_8, true);
EXPECT_LT(0, countNonZero(img));
// check that border is not corrupted
rectangle(img, origin,
Point(origin.x + labelSize.width, origin.y + labelSize.height),
Scalar::all(0), -1, 8);
//imshow("img", img);
//waitKey();
EXPECT_EQ(0, countNonZero(img));
origin = Point(10, labelSize.height + 10);
putText(img, text, origin, FONT_HERSHEY_SIMPLEX, 1.0, Scalar::all(255));
EXPECT_LT(0, countNonZero(img));
// check that border is not corrupted
rectangle(img, Point(10, 10), Point(labelSize.width + 10, labelSize.height + 10), Scalar::all(0), -1);
EXPECT_EQ(0, countNonZero(img));
}
typedef struct TextProp
{
const char* str;
bool ralign;
int weight;
bool italic;
} TextProp;
#ifdef HAVE_UNIFONT // there are other tests for text drawing, so the functionality is tested anyway,
// but this test needs concrete unicode font to compare the printed text
// (including CJK characters) with the reference picture from the database
TEST(Drawing, ttf_text)
{
string ts_data_path = TS::ptr()->get_data_path();
string custom_font_path = ts_data_path + "../highgui/drawing/";
FontFace sans("sans");
FontFace italic("italic");
Mat img(600, 1300, CV_8UC3);
TextProp text[] =
{
{"The quick brown fox jumps over lazy dog. Fly, start, finish, shuffle shuttle.", false, 400, false},
{"vechicle #5 detected; fps=123.45.\n", false, 600, false},
{"Съешь же ещё этих мягких французских булок, да выпей чаю!\n"
"Dès Noël où un zéphyr haï me vêt de glaçons würmiens je dîne\ndexquis rôtis de bœuf au kir à laÿ d’âge mûr & cætera!\n"
"“Falsches Üben von Xylophonmusik quält jeden größeren Zwerg”.", false, 400, true},
{"¡Oh tú, sabio encantador, quienquiera que seas,\n"
"a quien ha de tocar el ser coronista desta peregrina\n"
"historia, ruégote que no te olvides de mi buen Rocinante,\n"
"compañero eterno mío en todos mis caminos y carreras!\n", false, 300, false},
{"Ταχίστη αλώπηξ βαφής ψημένη γη, δρασκελίζει υπέρ νωθρού κυνός.", false, 400, false},
{"春眠不觉晓,\n处处闻啼鸟。\n夜来风雨声,\n花落知多少。\n"
" あなたはそれが困難見つけた場合 — あなたは正しい方向に向かっている。\n"
" 넌 모든 꽃들을 다 꺾어버릴 수는 있겠지만, 봄이 오는 걸 막을 수는 없어。 ", false, 400, false}
};
Scalar color(150, 80, 0);
for(int iter = 0; iter < 1; iter++)
{
//double ts = (double)getTickCount();
img.setTo(Scalar::all(255));
int sz = 20;
int x0 = 50, y0 = 70;
Point org(x0, y0);
int j = 0, column = 1;
for(const TextProp& t: text)
{
PutTextFlags flags = t.ralign ? PUT_TEXT_ALIGN_RIGHT : PUT_TEXT_ALIGN_LEFT;
if(t.ralign)
{
if(j > 0)
break;
if(column == 1)
{
column = 2;
org.y = y0;
}
org.x = img.cols - x0;
}
else
{
org.x = column == 1 ? x0 : img.cols/2;
}
FontFace& face = t.italic ? italic : sans;
//Rect r = getTextSize(img.size(), t.str, org, face, sz, t.weight, flags);
org = putText(img, t.str, org, color, face,
sz, t.weight, flags, Range());
//rectangle(img, r, Scalar(80, 0, 128), 1, LINE_AA);
org.y += sz + 10;
}
Scalar color2(80, 0, 128);
org = Point(img.cols - 500, 150);
putText(img, "Пробуем\n ", org, color2, italic, 80, 300,
PUT_TEXT_ALIGN_LEFT, Range());
org.x -= 90;
org.y += 130;
// testing alternative way to set the weight;
// in putText we use weight=0
italic.setInstance({CV_FOURCC('w','g','h','t'), 800<<16});
putText(img, "OpenCV", org, color2, italic, 120, 0,
PUT_TEXT_ALIGN_LEFT, Range());
org.y += 140;
org.x += 60;
putText(img, "打印文字", org, color2, sans, 100, 400,
PUT_TEXT_ALIGN_LEFT, Range());
//ts = (double)getTickCount() - ts;
//printf("iter=%d. ts=%.2fms\n", iter, ts*1000./getTickFrequency());
}
#if 0
//imwrite(ts_data_path + "../highgui/drawing/text_test.png", img);
imshow("test", img);
waitKey();
#else
Mat refimg = imread(ts_data_path + "../highgui/drawing/text_test.png", IMREAD_UNCHANGED);
//imshow("ref", refimg);
//imshow("actual", img);
//absdiff(refimg, img, refimg);
//imshow("diff", refimg);
//waitKey();
EXPECT_EQ(refimg.size(), img.size());
EXPECT_LT(cv::norm(refimg, img, NORM_L1), 6500);
#endif
}
#endif
}} // namespace