大海で生きたいマンのブログ

大海で生きたいな〜と思い、行動したことを残していくブログ

課題があったので(実質)初めてPython3でOpenCVを触ってみた

正月にDSのポケモンウルトラムーンを買ってのんびり過ごしていたら、学科の皆さんのツイートを見て
「はっ!!課題!」となったので急いで課題をやることに...
てことで、実質初めてのPython3×OpenCVを課題を通して触ったので、調べたこととかを載せてみようと思います。

とある講義の課題

課題の内容

「実写写真画像を加工してマンガ風の画像を生成するプログラム」を作成しなさい。
⇒実現に必要な機能をリストアップしてからコーディングすると良い。また、吹き出しや効果音等も好みに応じて追加して良い。できるだけカッコ良くマンガ化すること。 余力のある者は4コマ漫画にしても良い。ただし、4コマ漫画として面白くなければならない。

はい...とのことです。ギャグセンスには自信がないので、純粋に一つの画像を漫画風にしようと思いますw

今回漫画風にするのはこれ!!

f:id:ibuki0315:20180102180428j:plain:w300

はい、私の愛するpepsi。(これを写すと、高血圧だのとうるさい人達がいるのですがそんなのは気にしない。)

これを漫画風にするにあたり、Python3OpenCVを使うことにしました。手っ取り早く。
いつもならこの講義の課題はJavaでゴリゴリ書くのですが、今回はササっとやりたいのと、前期の実験3の画像処理班ではすごく中途半端に触ってしかいなかったので、やることにしました。
備忘録として、今回新しく学んだことを載せていきやす。

参考記事

・【Python/OpenCV】写真・画像を漫画風に加工
・【画像処理】写真を漫画風に加工する原理・仕組み

cvtColor

漫画風にするにあたってまずは、入力画像とスクリーン画像をグレースケール変換しないといけなかったので、OpenCVのcvtColorメソッドを使いました。

gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)

こんな感じで。引数に入力画像の変数と、cv2.COLOR_BGR2GRAYを与えればグレースケール変換ができるというメソッド。

resize

次に、入力画像とスクリーン画像の大きさを統一する必要があるので、OpenCVのresizeメソッドを使いました。

screen = cv2.resize(screen,(gray.shape[1],gray.shape[0]))

今回はこのように。スクリーン画像の変数と入力画像をグレースケール変換したgrayの横幅と縦幅の値を渡すことで、スクリーン画像の大きさを入力画像に合わせた。

Canny

次に、漫画風にしていくために、輪郭を検出する必要があるので、ここでもOpenCVのメソッド、Cannyメソッドを使いました。

edge = 255 - cv2.Canny(gray, 80, 120)

こんな感じで。引数にそれぞれ、入力画像、最小閾値、最大閾値を与えてエッジ検出をするメソッド。今回は入力画像にグレースケール変換した画像の変数、最小閾値、最大閾値をそれぞれ80、120にしてエッジ検出。
しかし、これでは真っ黒に輪郭が検出された画像のままなので、色を反転するために、画素値255の白から差し引く処理を追加で行っている。

bitwise_and

最後に,bitwise_andメソッド。このメソッドを使う前に、入力画像を白、黒、灰色の三値化を行った前提で。 以下のように用いた。

cv2.bitwise_and(gray, edge)

引数に配列をそれぞれ与え、ピクセル毎に論理積処理を行うメソッド。今回は、三値化をした画像grayとエッジ検出をして白ベースに反転させた画像edgeを引数に与えて、論理積を取る。これで目的の漫画風な画像にしている。

結果としてはこんな感じ。 f:id:ibuki0315:20180102185557j:plain:w300

最小閾値と最大閾値の間の値を持つところ(灰色の部分)を最初は、スクリーン画像に置き換えてたんだけど、なんか嫌だったので結局スクリーンなしの画像のほうが良さげ。ただもう少しその部分は工夫ができればよかったかも。
とりあえずこんな感じで、楽しく課題ができた一日でした〜。