LoginSignup
12
8

More than 5 years have passed since last update.

freetype対応したまとめを(Harfbuzzも足したい!)

Last updated at Posted at 2016-12-09

OpenCV Advent Calendar 2016、12月10日の記事です。

はじめに

cv::matに日本語も描画したい!って人向けのガイダンスになります。

何ができるのか

OpenCVのcv::matに直接フォントファイル使って日本語が書けるよ!!:smile:
image

a.cpp
#include <opencv2/opencv.hpp>
#include <opencv2/freetype.hpp>
#include <string>
#include <cstring>

int main(int argc, char **argv)
{
    std::string fontlist[] = {
"NotoSansCJKjp-Black.otf",
"NotoSansCJKjp-Bold.otf",
"NotoSansCJKjp-DemiLight.otf",
"NotoSansCJKjp-Light.otf",
"NotoSansCJKjp-Medium.otf",
"NotoSansCJKjp-Regular.otf",
"NotoSansCJKjp-Thin.otf",
"NotoSansMonoCJKjp-Bold.otf",
"NotoSansMonoCJKjp-Regular.otf",
"mplus-1c-black.ttf",
"mplus-1c-bold.ttf",
"mplus-1c-heavy.ttf",
"mplus-1c-light.ttf",
"mplus-1c-medium.ttf",
"mplus-1c-regular.ttf",
"mplus-1c-thin.ttf"
};

  int i;
  cv::freetype::FreeType2 ft2;
  ft2.setSplitNumber( 4 );
  cv::Scalar col ( 255,255,255 );

  cv::Mat src = cv::Mat::ones(800, 900, CV_8UC3) * 255;

  for(i=0;i<sizeof(fontlist)/sizeof(fontlist[0]);i++){
    ft2.loadFontData(fontlist[i], 0);

    ft2.putText(src, fontlist[i] + "これはharfbuzzのテストです",
      cv::Point(10 , 10 + i * 40), 30, col, -1, 16, false );
  }
  cv::imwrite("a.png", src);
}

hint

線幅 に -1を指定するとbitmapでの描画モードになります。それ以外ならばpathでの描画モードになります。
bitmapモードで、lineStyleに16を指定すると、8bit画像でのマージモードになります。

インストール手順

ここでは、Ubuntuでの作業手順を提示します。適宜、各自の環境に読み直してください。

  1. 必要なライブラリをインストールする $ sudo apt install libfreetype6-dev libharfbuzz-dev

2.フォントデータをダウンロードして、ワークフォルダに置く。

例えば、M+FONTSさん
http://mplus-fonts.osdn.jp/about.html#download
https://ja.osdn.net/projects/mplus-fonts/releases/62344

例えば、Google Noto Fontsさん
https://www.google.com/get/noto/

  1. OpenCVとcontribをダウンロード
$ cd ~ && mkdir opencv2 && cd opencv2
$ git clone https://github.com/Itseez/opencv.git
$ git clone https://github.com/Kumataro/opencv_contrib.git

改造版contribについては、最新レポジトリとってきてもいいけど、 https://github.com/Kumataro/opencv_contrib/tree/freetype2 の右上でダウンロードしてもよいかもしれません。一番良いのは、オリジナルのopencv_contribにマージする事ですけどね(ちらっちらっ)。

4 contrib付きでMakefileを作成する

$ cd opencv
$ mkdir build && cd build
$ cmake -D OPENCV_EXTRA_MODULES_PATH=~/opencv2/opencv_contrib/modules .

そうするとこんな感じになる。(ただし、なんかマージしたコードでコンパイル通らない!詳しくは最後の暫定対応で)

  OpenCV modules:
    To be built:                 core flann imgproc ml photo reg surface_matching video dnn freetype fuzzy imgcodecs shape videoio highgui objdetect plot superres ts xobjdetect xphoto bgsegm bioinspired dpm face features2d line_descriptor saliency text calib3d ccalib datasets rgbd stereo tracking videostab xfeatures2d ximgproc aruco optflow phase_unwrapping stitching structured_light

再実行すると、コンパイルするモジュール一覧に"freetype"が追加されていることを確認できるはず。出来ない場合、freetype2とharfbuzzのどちらかの存在が確認できていないかも?

5 コンパイルを実行する
sudo make install -j 8 install && ldconfig

6 サンプルコードを動かしてみる(前述)

a.out : a.cpp
        g++ a.cpp -O2 -o a.out `pkg-config opencv freetype2 harfbuzz --cflags --libs`

まとめ

  • これでもう日本語を描画するためだけに、convertをがりがり呼び出す必要はありません!
  • PRしたいけど(ほかのモジュールで)コンパイル通らないのは誰のせいかな?私?
  • Happy OpenCV life !!

明日(2016/12/11)は、 dandelion1124 さんの「OpenCVとNPPの連携」です。

以上、よろしくお願いいたします。

技術的な説明

bitmap描画の場合

harfbuzzにUTF-8文字列を渡すと、gid(Glyph id)の配列が戻ってくる。各gidを基にfreetype library側でグリフをレンダリング→cv::matに合成をしています。

image

<path描画の場合>
path描画用のcallback関数を登録しておきます。freetype library側がmoveやline,cubic,conicなどのパス描画コールバック関数を呼び出してきます。ただし、OpenCVでは直接ベジェ曲線を描画できないので、仕方がなくn分割の直線に変換して描画しています。

image

harfbuzzは何のための使っているのか?

単純にUTF-8から、unicodeを取り出すのは容易である。これだけならばharfbuzzを使う必然性は低い。だが、harfbuzzを使うとunicodeの正規化処理も実行してくれる。これにより、例えば「か」+「濁点」が、「が」として描画されるようになる。

なお、harfbuzz側で計算した座標情報は今回は使っていない。全部、freetype側が計算した座標情報に従っている。

暫定対応

  • 2016/12/10 最新版のopencvトランク使うと問題なかったので、下記コメントは削除。

2016/12/9現在ためしたらエラーがでたので当該エラー箇所を削除。

CMake Error at /home/kumataro/opencv2/opencv_contrib/modules/text/CMakeLists.txt:22 (ocv_add_testdata):
Unknown CMake command "ocv_add_testdata".

  • TEST付きでコンパイルすると、これもコンパイルエラーが発生する。

cmake-gui .. なんかで、TESTモジュールコンパイルを外す。

~~

12
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
8