質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.48%

  • C++

    3617questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • OpenCV

    1162questions

    OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

openCV 画素の書き換え

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 725

north_redwings

score 24

微分フィルタを画像にかけるプログラムを書いています。
流れは以下の通りです。

1.Vec3b型の2次元配列BGRに画素を代入する
(ただし,1回り大きく配列を取り, 周辺の画素を全て0に設定する)
2.縦方向の微分フィルタと横方向の微分フィルタとで分けて別々にかける
3.Vec3b型の2次元配列BGR_h, BGR_vに画素を代入する
4.BGR_h, BGR_vの値をImg_h, Img_vの画素に代入し, 書き換える

しかし、何度試しても画像が変わりません。
色々デバッグして画素は変わっている気がするのですが...

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>

using namespace std;
using namespace cv;

int main(int argc, char* argv[])
{
    Mat Img = imread("lena.jpeg");

    double h_filter[3][3] = { {-0.125, -0, -0.125}, {-0.25, 0, 0.25}, {-0.125, 0, 0.125} };
    double v_filter[3][3] = { {0.125, 0.25, 0.125}, {0, 0, 0}, {-0.125, -0.25, -0.125} };

    int width = Img.cols;
    int height = Img.rows;

    Vec3b BGR[width+2][height+2], BGR_h[width][height], BGR_v[width][height];
    int row, col;

    for (row=0; row<height; row++){
        for (col=0; col<width; col++){
            BGR[row+1][col+1] = Img.at<Vec3b>(row, col);

            BGR[0][col] = Vec3b(0, 0, 0);
            BGR[height][col] = Vec3b(0, 0, 0);
            BGR[row][0] = Vec3b(0, 0, 0);
            BGR[row][width] = Vec3b(0, 0, 0);
        }
    }
    int i, j;
    for (row=0; row<height; row++) {
        for (col=0; col<width; col++) {

            for (i=0; i<3; i++) {
                for (j=0; j<3; j++) {
                    BGR_h[row][col] += BGR[row+1-i+1][col-1+j+1] * h_filter[i][j];
                    BGR_v[row][col] += BGR[row+1-i+1][col-1+j+1] * v_filter[i][j];
                }
            }
        }
    }

    Mat Img_h = Img, Img_v = Img;
    for (row=0; row<height; row++){
        for (col=0; col<width; col++){

            // Img.at<Vec3b>(row, col) = Vec3b(0,0,0);
            cout << "Img_h.at<Vec3b>(" << row <<"," << col << ")="<< Img_h.at<Vec3b>(row, col) << endl;
            // Img_h.at<Vec3b>(row, col) = BGR_h[row][col];
            Img_h.at<Vec3b>(row, col) = Vec3b(0, 0, 0);
            // cout << "BGR_h[row][col] = " << BGR_h[row][col] << endl;
            cout << "代入後Img_h.at<Vec3b>(" << row <<"," << col << ")=" << Img_h.at<Vec3b>(row, col) << endl;;

            cout <<"\n";

            Img_v.at<Vec3b>(row, col) = BGR_v[row][col];
        }
    }


    // int bgr = BGR_h[4][4][0];
    // cout << BGR_h[4][4]*3 << endl;
    // cout << bgr << endl;

    imshow("test", Img);
    imshow("test_h", Img_h);
    imshow("test_v", Img_v);

    int key = waitKey(1000000);

    return 0;
}


とりあえず全てBGR_hはVec3b(0,0,0)で変更する様にしてでバックしてます。
ターミナルでの表示は,

Img_h.at<Vec3b>(0,0)=[12, 16, 35]
代入後Img_h.at<Vec3b>(0,0)=[0, 0, 0]

Img_h.at<Vec3b>(0,1)=[15, 19, 38]
代入後Img_h.at<Vec3b>(0,1)=[0, 0, 0]

Img_h.at<Vec3b>(0,2)=[10, 14, 32]
代入後Img_h.at<Vec3b>(0,2)=[0, 0, 0]

Img_h.at<Vec3b>(0,3)=[12, 15, 36]
代入後Img_h.at<Vec3b>(0,3)=[0, 0, 0]

Img_h.at<Vec3b>(0,4)=[9, 15, 34]
代入後Img_h.at<Vec3b>(0,4)=[0, 0, 0]

Img_h.at<Vec3b>(0,5)=[13, 16, 37]
代入後Img_h.at<Vec3b>(0,5)=[0, 0, 0]

Img_h.at<Vec3b>(0,6)=[9, 16, 33]
代入後Img_h.at<Vec3b>(0,6)=[0, 0, 0]

Img_h.at<Vec3b>(0,7)=[9, 16, 33]
代入後Img_h.at<Vec3b>(0,7)=[0, 0, 0]

Img_h.at<Vec3b>(0,8)=[11, 15, 33]
代入後Img_h.at<Vec3b>(0,8)=[0, 0, 0]

Img_h.at<Vec3b>(0,9)=[11, 15, 34]
代入後Img_h.at<Vec3b>(0,9)=[0, 0, 0]

Img_h.at<Vec3b>(0,10)=[9, 13, 31]
代入後Img_h.at<Vec3b>(0,10)=[0, 0, 0]
~~~
以下同様


イメージ説明
結果はこの様な形でそもそも元の画像も微妙に変わってしまっています...

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

 Mat Img_h = Img, Img_v = Img;


上記箇所において、コピーしているつもりかと思われますが、実際はデータはコピーされていません。

浅いコピーと深いコピー参照。

 Mat Img_h, Img_v;
 Img.copyTo(Img_h);
 Img.copyTo(Img_v);


とするのがご要望の動作(深いコピー)になります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/06/05 11:05

    なるほど!!!コピーに種類があってそこが問題だったんですね…
    もう一つ、よろしければ質問させてください。画像が正方形でない場合(上記もそうです)、右側が失われて左側が繰り返されています。どこが問題なのでしょうか?

    キャンセル

  • 2018/06/05 11:25

    それは、デバッグしてみないと、コードレビューだけではつらいっすねぇ。。。
    すぐにも動かす環境作れませんし。

    でも、以下のインデックスの取り方がなんとなく変な気がします。
    この辺を中心にデバッグしてみてはいかがでしょうか。
    BGR_h[row][col] += BGR[row+1-i+1][col-1+j+1] * h_filter[i][j];
    BGR_v[row][col] += BGR[row+1-i+1][col-1+j+1] * v_filter[i][j];

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.48%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 解決済

    python,opencvで円弧型の部分にのみ処理をしたい

    Python,OpenCVともに使うのが初めてです。 現在、類似画像検索のようなものを作っています。 そこで、画像の一部(円弧型)にある処理(ただ白いpixelを数えるだけ)を

  • 解決済

    テンプレートマッチングでの最大値の座標

    opencvでテンプレートマッチングを行っています。 以下の流れで、マッチング箇所を囲っているのですが、 最大値の座標が分からないため、cvrectangle内の+ temp

  • 解決済

    フーリエ変換・逆フーリエ変換後に値が振り切って画像に戻せません

    前提・実現したいこと Python+OpenCVで、カラー画像にフーリエ変換を行ってマスク処理をしたいと考えています。昨日からこちらの説明(鳥取大)を参考に、とりあえず動くところま

  • 受付中

    カメラで青い円を検出

    #include <stdio.h> #include <stdlib.h> #include <highgui.h> #include <cv.h> #include <cxco

  • 解決済

    OpenCVを使った笑顔検出での問題

    前提・実現したいこと OpenCVで元からあるサンプルコード「smiledetect.cpp」を用いて笑顔検出のシステムを作っています。 検出機能を実装中に以下の問題が発生しました

  • 解決済

    OpenCVを使って動画の書き出しができない

    aviファイルを読み込み,1フレームずつ間隔をSleep関数を用いて変化させて再生速度を変えるプログラムを作っています. 0倍速,等倍速,2倍速,3倍速,4倍速,5倍速の速度を行き

  • 受付中

    opencvで画像の切り抜き

    添付のようなアパレルの画像から輪郭を抽出、切り抜きを実現したいのですが、 経験が少ないため、どのようにアプローチすべきか悩んでします。 下記サイトを参考にプロセスを考えま

  • 解決済

    opencvで直線近似

    これらを輪郭近似し取得した輪郭の頂点を元に面積が一定以上の大きさのところだけ取り出すことで日差しの部分をカットできるのではないかと思ったのですがどのように取り組んでいいか

同じタグがついた質問を見る

  • C++

    3617questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • OpenCV

    1162questions

    OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。