プレモルCM画像を作る with openFrameworks
こんにちは,1000chです. 先週1週間,ギリシャはクレタ島まで学会にいって参りました. リゾート地なだけはあり良い景色がいっぱいでした. 中でも近くのサントリーニ島がとてもよい感じです.
せっかく良さげな写真が撮れたので,プレモルCM的な色抽出画像を作ってみたいと思います.
さてじゃーどう作るかってはなしですが,時間も余り無いので(リレー的な意味で)さらっとつくれるoFを使います. 色抽出はHSV空間を使えばまぁ良いでしょう.
しきい値設定のUI部分としてはofxUIを使います. 依存アドオンとしてofxXmlsettingsも使ってるみたいなので,併せて取り込んでおきます.
testapp.h
#pragma once #include "ofMain.h" #include "ofxUI.h" // add class testApp : public ofBaseApp{ public: void setup(); void update(); void draw(); void keyPressed(int key); void keyReleased(int key); void mouseMoved(int x, int y ); void mouseDragged(int x, int y, int button); void mousePressed(int x, int y, int button); void mouseReleased(int x, int y, int button); void windowResized(int w, int h); void dragEvent(ofDragInfo dragInfo); void gotMessage(ofMessage msg); // add from here void exit(); void setupGui(); void process(); void guiEvent(ofxUIEventArgs &e); ofxUISuperCanvas *gui0; ofImage src_img; ofImage dst_img; string filename; float min_hue; float max_hue; };
testapp.cpp
//書き換えたとこだけ抜粋 void testApp::setup(){ filename = "coke"; src_img.loadImage(filename + ".jpg"); dst_img.allocate(src_img.width, src_img.height, OF_IMAGE_COLOR); setupGui(); process(); } void testApp::setupGui(){ ofEnableSmoothing(); ofSetCircleResolution(60); min_hue = 100; max_hue = 200; gui0 = new ofxUISuperCanvas("SLIDER WIDGETS"); gui0->addSpacer(); gui0->addLabel("min_hue"); gui0->addSlider("min", 0.0, 255.0, &min_hue); gui0->addLabel("max_hue"); gui0->addSlider("max", 0.0, 255.0, &max_hue); gui0->autoSizeToFitWidgets(); ofAddListener(gui0->newGUIEvent,this,&testApp::guiEvent); } void testApp::process(){ ofColor src_col,dst_col; for(int i=0; i<dst_img.height; i++){ for (int j=0; j<dst_img.width; j++) { src_col = src_img.getColor(j, i); if( min_hue < src_col.getHue() && src_col.getHue() < max_hue){ dst_col = src_col; } else { dst_col = ofColor(src_col.g); } dst_img.setColor(j, i, dst_col); } } dst_img.update(); } //-------------------------------------------------------------- void testApp::guiEvent(ofxUIEventArgs &e){ process(); cout << min_hue << ":" << max_hue << endl; } //-------------------------------------------------------------- void testApp::draw(){ ofPushMatrix(); float rate = ofGetWidth() / (float)src_img.width / 2; ofScale(rate,rate); src_img.draw(0, 0); dst_img.draw(src_img.width, 0); ofPopMatrix(); } //-------------------------------------------------------------- void testApp::exit() { delete gui0; } //-------------------------------------------------------------- void testApp::keyPressed(int key){ switch (key) { case 'g': { gui0->toggleVisible(); break; } case 's': { string save_filename = filename + ofGetTimestampString() + ".jpg"; dst_img.saveImage(save_filename); cout << "save as " << save_filename << endl; break; } default: break; } }
HSVと言いつつ色相しか使ってないですけどねw ofColorのグレースケール化手法がすぐにわからなかったので,とりあえずココ参考にgreen要素そのものを使ってます.
実行結果
では.先程の画像を変換してみます.
動作動画はこちら.
入力画像1
出力画像1
海と教会の色がほぼほぼ同じだった(´・ω・`) s,v要素も使えばよいのかね.
入力画像2
出力画像2(青抜き)
プールだけのこった!
出力画像2(赤抜き)
いい感じに花が抜けています.
ほかにもいくつかやってみましょう.
入力画像3
出力画像3(赤抜き)
ちょっち手が残った(´・ω・`)
入力画像4
出力画像4(赤抜き)
ちょっとバランスが難しいかな?一応花は抜けた.
入力画像5
出力画像5(青抜き)
ちょっち空が残った(´・ω・`)
出力画像5(茶抜き)
奇麗に要塞が抜けたw
まとめ
とまぁ色抽出するプログラムを作ってみました.画像処理を始めて勉強した頃を思い出しますね.コーラの画像とかは意外といい出来では無いでしょうか.
しかし,素材的に海と空がかぶってしまうのがちょっと残念ですね.色相だけでなく,彩度,明度も扱えば改善されるのかなぁ.あとはドラッグ範囲のみに処理を行うとか.いずれやってみるかな.
ま,とりあえず今日はこんなとこでー. リレービハインド状態なので明日もがんばって何か書かないと!