かいてんずし

築地サーバーを取り巻く寿司(PC)たちの日常。

RMagickで画像の中の黒い文字のみ抽出する

動機

文字認識の精度を上げるために、画像の中の黒い文字の部分だけを抽出したい。
(デコられた文字画像のデコってる部分を剥がしたい)

方法

RMagickというgemを使いました。

imagemagickをインストール! (Ubuntu 14.04.2の場合)

sudo apt-get install imagemagick libmagickwand-dev

RMagick gemをインストール!

gem install rmagick

実行

# RMagickで画像のうちグレースケール部分のみ取得

include Magick

def grayscale(file)
  img = ImageList.new(file)
  white = Magick::Pixel.new(255*256,255*256,255*256) # この色で塗りつぶす

  for y in 0...img.rows
    for x in 0...img.columns
      src = img.pixel_color(x, y) # 元画像のピクセルの色を取得
      rg = (src.red - src.green).abs # 赤の値と緑の値の差分
      gb = (src.green - src.blue).abs # 緑の値と青の値の差分
      br = (src.blue - src.red).abs # 青の値と赤の値の差分
      # 白の場合は何もしない
      if src==white
      # グレースケール以外の場合、白で塗りつぶす
      elsif !((rg<10*256)&&(gb<10*256)&&(br<10*256)) 
        img.pixel_color(x,y,white)
      end
    end
  end
  img.write file # 上書きする
end

黒い文字を抽出したいので、各ピクセルの色を検出し、黒でなければ白く塗りつぶす。
しかし、黒(0,0,0)だけを指定してしまうと、文字も白く塗りつぶされてしまう。
そこで、グレースケール(赤の値=緑の値=青の値)以外を白く塗りつぶす、という処理をすることにした。
(白もグレースケールに入っているので先に除外しなくてはいけないことに注意!)

「それぞれの値の差が10以内」(255のうち)に指定したらちょうどいい感じになったけど、環境や処理したい画像によっては違うかもしれません。

結果