OpenCVでカメラ画像をアニメ風にする
OPenCVでカメラから取得した映像をアニメ風にして表示するプログラムを書いた.具体的には,取得した画像の各ピクセルのRGB値を適当な段階に量子化する.その上にCanny法で検出したエッジを黒で重ねている.結果として,カメラで取得した画像が以下のようになる.
こういう画像処理はVideo Absractionというらしい.
本当は,ofxCvアドオンを使って,openFrameworksで作りたかったが,上手く動かすことができず.OpenCV自体をもっと勉強してからもう一回チャレンジする.
以下がコード.
main.cpp
//
// main.cpp
// videoAbstraction
//
// Created by aa_debdeb on 2015/11/16.
//
//
#include
#include
#include "opencv2/opencv.hpp"
cv::Mat getAnimeMat(cv::Mat img){
cv::Mat canny_img, anime_img;
cv::Canny(img, canny_img, 50, 200);
anime_img = cv::Mat(cv::Size(img.cols, img.rows), CV_8UC3);
int color_step_num = 8;
float color_step_size = float(255) / color_step_num;
for(int y = 0; y < img.rows; y++){
for(int x = 0; x < img.cols; x++){
if(canny_img.at(y, x) == 255){
anime_img.at(y, x) = cv::Vec3b(0, 0, 0);
} else {
cv::Vec3b img_color = img.at(y, x);
cv::Vec3b anime_color = cv::Vec3b(255, 255, 255);
for(int ci = 0; ci < 3; ci++){
for(float level = color_step_size / 2; level < 255; level += color_step_size){
if(fabs(img_color[ci] - level) <= color_step_size / 2){
anime_color[ci] = level;
break;
}
}
}
anime_img.at(y, x) = cv::Vec3b(anime_color[0], anime_color[1], anime_color[2]);
}
}
}
return anime_img;
}
int main(int argc, const char * argv[]) {
// cv::Mat img = cv::imread("lenna.jpg", 1);
// if(img.empty()) return -1;
//
// cv::Mat anime_img = getAnimeMat(img);
// cv::imshow("anime image", anime_img);
// cv::waitKey(0);
cv::VideoCapture cap(0);
cv::Mat img;
while(cv::waitKey(1) != 'q'){
cap >> img;
cv::Mat anime_img = getAnimeMat(img);
cv::imshow("anime image", anime_img);
}
}
OpenCV/videoAbstraction at master · aa-debdeb/OpenCV
参考
- コンピュータビジョンのセカイ - 今そこにあるミライ (39) iPhoneアプリ「漫画カメラ」に見るコンピュータビジョンの実応用例 | マイナビニュース
- コンピュータビジョンのセカイ - 今そこにあるミライ (40) iPhoneアプリ「漫画カメラ」で使われている画像処理手法その1 | マイナビニュース
- コンピュータビジョンのセカイ - 今そこにあるミライ (41) iPhoneアプリ「漫画カメラ」で使われている画像処理手法その2 | マイナビニュース
- コンピュータビジョンのセカイ - 今そこにあるミライ (42) 漫画カメラで使われる漫画風画像生成とトゥーンシェーディングの違い | マイナビニュース
- OpenCVとVisual C++による画像処理と認識(2)― 原画像をRGB成分に分解してピクセル単位の画像処理をする ---
- 画像処理 — OpenCV-CookBook