「忠犬もちしば」のAIボットを作ろう!

インテルが提供しているOpenCVで画像処理を行う為に画面全体ではなく部分的にもしくは強弱を付けて「ぼかし」をかけたいのですがどの様に行えば良いのか分かりません。部分的に四角く行うにはROIなど使用すれば良いのですが、例えば円形や上下に向けて「ぼかし」が強くなる方法が分からないのです。添付しました画像のようなグラデーションで作成したマスク画像を利用してグラデーション色の強弱で「ぼかし」の強弱を付ける方法などないのでしょうか?どなかた分かる方がいましたらお手数ですがお知らせください。宜しくお願い致します。(OpenCVでは無理であればC++などで再現するサンプルプログラムなど掲載されているサイトなどでも構いません!)

「OpenCVでマスク処理で「ぼかし」は可」の質問画像

このQ&Aに関連する最新のQ&A

A 回答 (3件)

No.2の追記ですが、先ほどの疑似コードは、



OutputImage[i][j].R = (SourceImage[i][j].R * (255 - MaskImageBrightness[i][j]) + UniformFeatheredImage[i][j].R * (MaskImageBrightness[i][j])) / 255;
OutputImage[i][j].G = (SourceImage[i][j].G * (255 - MaskImageBrightness[i][j]) + UniformFeatheredImage[i][j].G * (MaskImageBrightness[i][j])) / 255;
OutputImage[i][j].B = (SourceImage[i][j].B * (255 - MaskImageBrightness[i][j]) + UniformFeatheredImage[i][j].B * (MaskImageBrightness[i][j])) / 255;

のように最大輝度で除算する必要がありました。
重ね重ね失礼いたしました。
    • good
    • 0

No.1の回答者ですが、「画面全体ではなく部分的にもしくは強弱を付けて」ということなので、No.1の方法だけでは一様なぼかし処理でしかないですね。

申し訳ありません。

PhotoshopやGIMPで、マスク画像のチャンネルを8bppの選択範囲として読みこんで、選択範囲内にぼかしフィルタをかける処理と同じものでしょうか?
だとすれば、下記のようなアルゴリズムが最も単純かと思われます。

1. 任意の強度で、まず画像全体に対して一様にぼかしをかける。

2. 元画像の各ピクセルと、一様ぼかし画像の各ピクセルを合成する際に、マスク画像の各ピクセルを重みとして利用する。

下記は入出力画像が同じサイズのRGBカラー画像、マスク画像が同じサイズの8bitグレースケール画像だと仮定した場合の疑似コードです。

OutputImage[i][j].R = SourceImage[i][j].R * (255 - MaskImageBrightness[i][j]) + UniformFeatheredImage[i][j].R * (MaskImageBrightness[i][j]);
OutputImage[i][j].G = SourceImage[i][j].G * (255 - MaskImageBrightness[i][j]) + UniformFeatheredImage[i][j].G * (MaskImageBrightness[i][j]);
OutputImage[i][j].B = SourceImage[i][j].B * (255 - MaskImageBrightness[i][j]) + UniformFeatheredImage[i][j].B * (MaskImageBrightness[i][j]);


Photoshopなどではこんな単純なことはやっていなくて、もっと最適化された高速なアルゴリズムで実装されているのだと思いますが、僕にはせいぜいSSEなどを使うことくらいしか思いつきません。

こんな情報でも参考になるでしょうか?
    • good
    • 0

下記サイトではOpenCVと3x3ガウス フィルタによるぼかし処理(+離散フーリエ変換による高速化)の実装例が紹介されていますが、このフィルタをお手持ちのマスク画像に置き換えるようにすれば良いのでは?


カーネルの各レート(重み)を画像輝度から計算するわけですが、フィルタ画像輝度の総和を事前に求めて、各レートの総和が1となるように正規化する必要があります。

http://iphone.moo.jp/app/?p=955
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QOpenCV でのROIの指定方法について

いつもお世話になっております.
OpenCVに関する質問です.
FastFeatureDetectorやGoodFeaturesToTrackDetector等の特徴点検出器を入力画像の特定の部分に対して行うために,入力画像に対してROIを設定したのですが上手くいかない場合があって困っています.

たとえば,
入力画像(640*480)に対して,
左上(0,0)右下(640,480)や左上(0,0)右下(320,240)を矩形領域を指定すれば上手くいくのですが,
左上(10,10)右下(640,480)や左上(320,240)右下(640,480)だと,結果がズレてしまいます.

下記のソースコードで
---------------------------------------------------------------
cv::Rect* roi = new cv::Rect(roi_x, roi_y, roi_w, roi_h);
cv::Mat* InuptImage = new cv::Mat(640, 480, CV_8UC1, data);//dataはbyte型
InuptImage = new cv::Mat(*InuptImage, *roi);
---------------------------------------------------------------
(roi_x, roi_y, roi_w, roi_y)が
(0, 0, 640, 480)や(0, 0, 320, 240)の場合は上手くいくのですが,
(10, 10, 630, 470)や(320, 240, 320, 240)の場合には,特徴点の位置がずれたり,全体的に縮小されたりします.

どこに問題があるのでしょうか?

OpenCVは2.3で,言語はC++です.
アドバイス宜しくお願い致します.

いつもお世話になっております.
OpenCVに関する質問です.
FastFeatureDetectorやGoodFeaturesToTrackDetector等の特徴点検出器を入力画像の特定の部分に対して行うために,入力画像に対してROIを設定したのですが上手くいかない場合があって困っています.

たとえば,
入力画像(640*480)に対して,
左上(0,0)右下(640,480)や左上(0,0)右下(320,240)を矩形領域を指定すれば上手くいくのですが,
左上(10,10)右下(640,480)や左上(320,240)右下(640,480)だと,結果がズレてしまいます.

下記のソースコードで
---...続きを読む

Aベストアンサー

オフセットは必ず必要です。ROIを指定する前の画像の全体のサイズと、本来の画像の左上から、ROIの左上の座標のオフセットは、locateROI メソッドで取得することができます。

実際には、オフセットを考慮して点群座標を変換するか、特徴点を描画したい場合などでは、元の画像ではなく ROI で切り取った画像に対して描画を行います。


参考まで。



// okwave01.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//

#include "stdafx.h"
#include <opencv2/opencv.hpp>

int main(int argc, char argv[])
{
const std::string FILE_PATH("lena.jpg");
//sample.bmpは640*480のRGBの画像

cv::Mat rgb_img = cv::imread(FILE_PATH);
// 画像読み込み

cv::Mat gray_img;
cv::cvtColor(rgb_img, gray_img, CV_BGR2GRAY);
// グレースケール画像に変換

const cv::Point ROI_TL(rgb_img.rows * 0.25, rgb_img.cols * 0.25);
const cv::Rect RECT(
rgb_img.rows * 0.25, rgb_img.cols * 0.25,
rgb_img.rows * 0.5, rgb_img.cols * 0.5);
// 中心 だけを切り取る ROI を作成。

cv::Mat rgbimage_roi = rgb_img(RECT);
cv::Mat grayimage_roi = gray_img(RECT);
// ROI による切り取り。


std::vector<cv::KeyPoint> corners;
// FAST 頂点座標の保存用変数

cv::FAST(grayimage_roi, corners, 10, true);

for (auto it = corners.begin(); it != corners.end(); ++it) {
cv::circle(grayimage_roi, it->pt, 1, cv::Scalar(255), 2);
// ROI を通してグレイスケール画像に書き込む

cv::circle(rgb_img, ROI_TL + cv::Point2i(it->pt), 1, cv::Scalar(0, 0xff, 0), 2);
// オフセットを考慮して直接RGB画像に書き込む
}

cv::imshow("RGB IMAGE", rgb_img);
cv::imshow("GRAY IMAGE", gray_img);
return cv::waitKey();
}

オフセットは必ず必要です。ROIを指定する前の画像の全体のサイズと、本来の画像の左上から、ROIの左上の座標のオフセットは、locateROI メソッドで取得することができます。

実際には、オフセットを考慮して点群座標を変換するか、特徴点を描画したい場合などでは、元の画像ではなく ROI で切り取った画像に対して描画を行います。


参考まで。



// okwave01.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//

#include "stdafx.h"
#include <opencv2/opencv.hpp>

int main(int argc...続きを読む

Qsleep()関数について

"数秒おきに警報をn回鳴らすプログラム"をC言語で作成しようと
考えています。

プログラム実行環境はWindowsですが、
sleep()関数は使用できないのでしょうか??

仮に使用できない場合、この関数に代わる関数や代替方法が
あれば教えて頂けませんでしょうか? 宜しくお願いします。

Aベストアンサー

正確な動作でも構わなければ
windows.hをインクルードして
Sleep()関数を使いましょう.
http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200207/02070061.txt

しかし,正確に数秒おきに動作を行いたい場合はマルチメディアタイマ等を使いましょう.
マルチメディアタイマはミリ秒間隔でコールバック関数を呼び出すことができます.
timeSetEventを用いてコールバック関数の登録を行うことができます.
timeKillEventでコールバック関数の解除を行うことができます.

多分他にも方法があると思うのですが…私はこれぐらいしか知りません^^;

参考URL:http://www.katto.comm.waseda.ac.jp/~katto/Class/GazoTokuron/code/time.html

QC++ でファイルを消す関数(??)

C++ でコンソールアプリケーションを作っています。

“Hello, world!” から数ヶ月しか経過していない,初心者です。

C++ で計算プログラムを組んでいて,計算の途中結果を一時的に保存するため

ofstream ofs(計算結果を一時的に保存するファイル);

のように,一時的に計算結果を保存するテキストファイルを生成しています。

計算を実行後には,このファイルには(ファイル管理の簡素化のため)消えておいてほしいのですが,
C++ に特定のファイルを消す関数(?)などは,あるのでしょうか?

初心者につき,変な質問をしているかもしれませんが,ご教授いただければ幸いです。

Aベストアンサー

既に回答が出ているように、<cstdio>ヘッダで宣言されているstd::remove関数がそれにあたります。

ところで、大きなお世話かも知れませんが、一時的なワーク領域に使うだけであれば、よほど大きなデータでない限り、std::ostringstreamを使って文字列に格納した方が扱いやすいと思います。

Qファイルやディレクトリの存在確認を行う方法

ファイルをオープンするのはfopenでOKですが、ファイルやディレクトリの存在確認を行う方法が知りたいです。

何か組み合わせて作るものなのでしょうか?
perlとか便利な演算子があるのですが、C/C++って器用ではないですね。
これは処理系?依存の内容ですか?

私の環境は VC6, VC2005 Windows2000です。

Aベストアンサー

int access(const char* path, int mode);
int stat(const char* path, struct stat* sb);

かな?
MSDN を引くと _access_s() を使えとか書いてあるけど。

Q魚眼レンズの画像処理

魚眼レンズで撮影した画像って、ひずんでますよね。
これを普通に(って何が普通かと言う問題はあるけれど)直す
処理プログラムをおしえていただけませんか?

できれば、教科書的なものでなく、サンプルプログラムがあれば
うれしいんですが・・・
言語は、C以上の高級言語ならたいていわかるので
せめてポインタだけでも・・

お願いします。

Aベストアンサー

代数幾何の射影変換で多分出来ると思います
通常画像を射影変換して魚眼レンズで見たような画像に出来るので魚眼レンズの射影行列の逆行列で変換してやれば元の画像に戻るはずです

元画像をN、射影行列をA、その逆行列をA^-1とした時、
NAが魚眼レンズ画像となるので、それにA^-1をかけると
NAA^-1 = N(AA^-1)
= N1
= N
で、元画像に戻ります

サンプルプログラムは「アフィン変換」や、「射影変換」などで検索すれば出てくると思います
または3D Gameのライブラリを見ればまず載っているはずです

参考URL:http://www.microsoft.com/japan/developer/library/default.asp?URL=/japan/developer/library/jpdx6sdk/_dx_the_projection_tr

Qグレースケール画像の画素値を得る

OpenCVを使わずにC言語で、グレースケール画像を読み込んで、各画素をそれに対応する配列に格納するプログラムを作りたいと思っています。
しかし、C言語で画像を読み込む方法や、各画素の画素値を得る方法がわかりません。どなたかご存知の方がいらしたら、教えてください。宜しくお願いします。

Aベストアンサー

グレースケール画像と言っても、フォーマット(内部のデータ形式)が
なんなのかわからないと、読み込みアルゴリズムが考えられません。


jpegの様な、圧縮が入っているフォーマットだと、非常に面倒です。
http://www14.ocn.ne.jp/~setsuki/ext/jpg.htm

逆に、pgmのように画素値をそのままバイナリかアスキーで
書き込んでいるだけなら、freadして配列に格納していくだけです。
画素値が知りたい場合は、配列の場所を指定してfprintでもすればよいでしょう。
http://www.not-enough.org/abe/manual/command/netpbm/pgm.html


方針としては、以下の二つが考えられます。

1.プログラムが対応する画像フォーマット種類を決め、
  そのフォーマットを調べ、対応アルゴリズムを構築する

2.pgmフォーマット読み込みプログラムを作成する。
  別途、画像変換ソフトを用意し、どんな画像でもpgmに変換してから
  プログラムで使用する。

画像変換ソフト例:IrfanView
http://www.forest.impress.co.jp/lib/pic/piccam/picviewer/irfanviewjp.html
画像を読み込んで、名前を付けて保存->pgmで保存


以上、参考になれば幸いです。

グレースケール画像と言っても、フォーマット(内部のデータ形式)が
なんなのかわからないと、読み込みアルゴリズムが考えられません。


jpegの様な、圧縮が入っているフォーマットだと、非常に面倒です。
http://www14.ocn.ne.jp/~setsuki/ext/jpg.htm

逆に、pgmのように画素値をそのままバイナリかアスキーで
書き込んでいるだけなら、freadして配列に格納していくだけです。
画素値が知りたい場合は、配列の場所を指定してfprintでもすればよいでしょう。
http://www.not-enough.org/abe/manual/com...続きを読む

Q色混ぜのアルゴリズム

このジャンルでお願いします。

例えば絵の具などで黄色と青色を混ぜると緑色(またはそれに近い色)
になると思いますが、これをプログラムで再現しようとすると
(白色)rgb(255,225,255) = (黄色)rgb(255,225,0)+(青色)rgb(0,0,255)
になってしまいます・・・
どのような割合でrgbを調節すれば、理想とする結果が得られるのでしょうか?

Aベストアンサー

★アドバイス
・この質問は絵の具と同じ感じで色を混ぜ合わせるアルゴリズムですか?
 そう解釈しましたので『半透明処理』で調べればよいと思います。
 例:
 http://eternalwindows.jp/graphics/bitmap/bitmap11.html→『アルゴリズム』
 ここに色を混ぜ合わせる公式があります。→RGB方式
 抜粋すると
 『dest = src * (alpha / 255) + dest * (1 - (alpha / 255));』
 です。これは赤・緑・青の1つの成分であるため3つ処理します。
 詳しくは次のサイトなどを参考にして下さい。
 http://www.sm.rim.or.jp/~shishido/toumei.html→『パレットによる半透明処理』
 http://www13.plala.or.jp/kymats/study/MULTIMEDIA/bmp_semitransparent.html→『半透明処理』
 http://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%AB%E3%83%95%E3%82%A1%E3%83%96%E3%83%AC%E3%83%B3%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0→『アルファブレンド』
・ネット検索するときは『半透明』または『半透明処理』とか、
 『アルファブレンド』『AlphaBlend』で調べます。
 API関数では
 http://msdn.microsoft.com/ja-jp/library/cc428300.aspx→『AlphaBlend』
 がります。

考え方:
『黄色』と『緑色』を1:1で混ぜるとき(RGB方式)

黄色=250,240,0(これを背景と考える)
緑色=0,230,0(こちらを前景と考える)
となり alpha=128(50%) とすると

赤輝度= 0 * (alpha / 255) + 250 * (1 - (alpha / 255))=124
緑輝度=230 * (alpha / 255) + 240 * (1 - (alpha / 255))=177
青輝度= 0 * (alpha / 255) + 0 * (1 - (alpha / 255))=0
となります。

よって『黄色』と『緑色』を1:1の比(50%)で混ぜ合わせると
赤輝度=124
緑輝度=177
青輝度=0

RGB=124,177,0
となります。

CYMも同じ考えて混ぜ合わせれば良いでしょう。

参考URL:http://eternalwindows.jp/graphics/bitmap/bitmap11.html

★アドバイス
・この質問は絵の具と同じ感じで色を混ぜ合わせるアルゴリズムですか?
 そう解釈しましたので『半透明処理』で調べればよいと思います。
 例:
 http://eternalwindows.jp/graphics/bitmap/bitmap11.html→『アルゴリズム』
 ここに色を混ぜ合わせる公式があります。→RGB方式
 抜粋すると
 『dest = src * (alpha / 255) + dest * (1 - (alpha / 255));』
 です。これは赤・緑・青の1つの成分であるため3つ処理します。
 詳しくは次のサイトなどを参考にして下さい。
 http://www...続きを読む

QOpenCVでの画像サイズ取得について教えてください。

OpenCVでの画像サイズ取得について教えてください。
rawデータをjpgにして取得し、その画像を4分割したいのですがエラーが3つ出てしまいます。
環境はVisual Studio2008です。
いろいろと調べたのですが、原因や対策がはっきりわからず、書き変えてもNGで困っています。

エラー:その1
「error LNK2028:未解決のトークン(0A00007B)"extern "C" struct IplImage *_cdecl cvLoadImage(char const roi.obj*.int)"(cvLoadImage@@$$J0YAPAU IplImage@@PBDH@Z)が関数"int _codecl main(int,char * *)"(?main@@$$HYAHHPAPAD@Z)で参照されました。」
エラー:その2
「error LNK2019: 未解決の外部シンボル"extern "C" struct IplImage * codecl cvLoadImage(char const *.int)" (?cvLoadImage@@$$J0YAPAU IplImage@@PBDH@Z)が関数"int_codecl main(int, char * *)" (?main@@$$HYAHHPAPAD@Z)で参照されました。」
エラー:その3
「fatal error LNK1120: 外部参照2が未解決です]

'==================
#pragma warning(disable : 4819)
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
#define DIVX (4)
#define DIVY (4)
#define DIVXY (DIVX*DIVY)

int main (int argc, char **argv)
{
int w, h

IplImage *img=0;
img=cvLoadImage("C:\・・・\\testfile.jpg, CV_LOAD_IMAGE_GRAYSCALE);

w = img->width - img->width % DIVX + DIVX;
h = img->height - img->height % DIVY + DIVY;

printf("幅は%w, 高さは%h です。 \n");
}
'===============================================

画像サイズを取得し、画像を4分割したあと、画素値を変更したいと思っています。
できればjpgに変換せず、rawデータそのものの精度の画像を直接扱いたいのですが、
その場合、cvLoadImageでどう表記すると実現できるのでしょうか。
また、OpenCVのグレースケールは、何チャンネルなのでしょうか。

プログラム経験はありますが、OpenCVを使うため、C言語の勉強も始めたばかりです。
なにか見当違いな質問をしていたら申し訳ありません。
お忙しいところすみませんが、もしどなたか解決策をアドバイスいただける方がいらっしゃると
大変助かります。
どうぞ宜しくお願い致します。

OpenCVでの画像サイズ取得について教えてください。
rawデータをjpgにして取得し、その画像を4分割したいのですがエラーが3つ出てしまいます。
環境はVisual Studio2008です。
いろいろと調べたのですが、原因や対策がはっきりわからず、書き変えてもNGで困っています。

エラー:その1
「error LNK2028:未解決のトークン(0A00007B)"extern "C" struct IplImage *_cdecl cvLoadImage(char const roi.obj*.int)"(cvLoadImage@@$$J0YAPAU IplImage@@PBDH@Z)が関数"int _codecl main(int,char * *)"(?main@@$$HYAHH...続きを読む

Aベストアンサー

>より幅のある数字の情報を元に、機械がもう少し緻密な判断ができるようにするには、
>通常は何チャンネルを使うのがいいでしょうか。

それは「チャンネル数」ではなく「深さ/精度」です。
グレースケールは「明るさ」というチャンネル1つで表わすものです。その数値の範囲に、たとえば8bit整数(0~255)とか16bit整数(0~65535)とかの「深さ」があります。
また、浮動小数点を使った表現もできます。32bit(float型相当)と64bit(double型相当)のものが使えます。

チャンネル数は例えば、明るさの他に色相,彩度の3チャンネルとか、RGBの3チャンネルとかです。

>(グレースケールにもRGBで表現させるなど、何パターンかあるようですが)
すべての色をR=G=Bにすれば、実質グレースケールです。RGBカラーにしか対応していないフォーマットでグレースケールを表現するときに使います。

>チャンネル数の問題ではなく、その後どういう処理をするか、がポイントでしょうか。

浮動小数点を使って精度を上げた方がよいケースも、逆に、2値化した方がいいケースもあります。

>より幅のある数字の情報を元に、機械がもう少し緻密な判断ができるようにするには、
>通常は何チャンネルを使うのがいいでしょうか。

それは「チャンネル数」ではなく「深さ/精度」です。
グレースケールは「明るさ」というチャンネル1つで表わすものです。その数値の範囲に、たとえば8bit整数(0~255)とか16bit整数(0~65535)とかの「深さ」があります。
また、浮動小数点を使った表現もできます。32bit(float型相当)と64bit(double型相当)のものが使えます。

チャンネル数は例えば、明るさの他に色相,彩度の3...続きを読む

QOpenCv 透明度について

OpenCv 透明度について

透明度を表すRGBAのA(アルファチャネル)をいじって画像の透明にしたいのですが、いじってみてもなにも変化がありません。
なにが悪いのかわかりません


↓こんな感じでやってます。

// 画像を読み込む
src_img = cvLoadImage(src_imgfile,CV_LOAD_IMAGE_COLOR);

//RGBA変換
dst_img = cvCreateImage(cvGetSize(bg_img),IPL_DEPTH_8U,4);
cvCvtColor(bg_img,dst_img,CV_RGB2RGBA);

//透明度をいじる
for ( int y = 0 ; y < dst_img->height ; y++ )
{
for ( int x = 0 ; x < dst_img->width ; x++ )
{

dst_img->imageData[dst_img->widthStep * y + x * 4 + 3] = -255;

}
}

Aベストアンサー

http://opencv.jp/opencv-2.1/c/drawing_functions.html
>また,この関数は,アルファ透過をサポートしません.目的画像が4チャンネルである場合でも color[3] には,単に新たなピクセル値がコピーされるだけです.したがって,もし半透明な形状を描画したい場合は,それを別のバッファに描画してから画像とブレンドするとよいでしょう.

http://opencv.jp/opencv-2.1/c/reading_and_writing_images_and_video.html
> cv::LoadImage
> 現在の実装では,アルファチャンネルがもしあったとしても,出力画像からは取り除かれることに注意してください.例えば,4チャンネルRGBA画像は,RGB画像として読み込まれます

>cv::SaveImage
> この関数では,8ビットシングルチャンネル,あるいは3チャンネル(チャンネルは ‘BGR’ の順番)画像のみを保存することができます


以上のように、4チャンネルの画像を作ることはできますが、それをファイルに読み書きしたり、画面表示したりはできません。
アルファチャンネルに対応した別のライブラリを使うなどの工夫が必要です。

http://opencv.jp/opencv-2.1/c/drawing_functions.html
>また,この関数は,アルファ透過をサポートしません.目的画像が4チャンネルである場合でも color[3] には,単に新たなピクセル値がコピーされるだけです.したがって,もし半透明な形状を描画したい場合は,それを別のバッファに描画してから画像とブレンドするとよいでしょう.

http://opencv.jp/opencv-2.1/c/reading_and_writing_images_and_video.html
> cv::LoadImage
> 現在の実装では,アルファチャンネルがもしあったとしても,出力画像からは取...続きを読む


人気Q&Aランキング