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

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

ただいまの
回答率

91.04%

  • C++

    2850questions

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

  • OpenCV

    794questions

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

C++で畳み込み画像処理を実装したい

解決済

回答 2

投稿 編集

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

fu-semo

score 1

C++で畳み込みを実装したい

C++でopencvを用いて畳み込みを実装しています
filter2Dなどの関数がある事は知っていますが、自分で関数を作ります。
自分で実装したコードはエラーは出ませんが出力が元の画像とはかけ離れたものになってしまいます

原画像、出力画像

原画像
イメージ説明

出力画像
イメージ説明

該当のソースコード

void convolution(Mat& src, Mat& mask){
  // src:原画像 mask:畳み込むフィルター
  int srcW = src.rows;
  int srcH = src.cols;
  int maskW = mask.rows;
  int maskH = mask.cols;

  // フィルターの半径
  int rx=(maskW-1)/2;
  int ry=(maskH-1)/2;

  // 出力画像を初期化
  dst=Mat::zeros(srcW, srcH, CV_8U);

  for(int x=0; x<srcW; x++){
    for(int y=0; y<srcH; y++){
      double sum=0;

      for(int i=0; i<maskW; i++){
        int pointx = x-rx+i;
        for(int j=0; j<maskH; j++){
          int pointy = y-ry+j;
          // pointが原画像の中である(原画像の外を参照する場合は何もしない)
          if((pointx>=0 && pointx<srcW) && (pointy>=0 && pointy<srcH)){
            // フィルターと原画像の積を総和する
            sum+=kernel.at<unsigned char>(i,j)*src.at<unsigned char>(pointx,pointy);
          }
        }
      }
      // 結果を出力画像に入れる
      dst.at<unsigned char>(x,y)=sum;
    }
  }
/* 画素値を0−255にスケーリングする事を試みましたが、結果が変わりませんでした
  float fmin=FLT_MAX;
  float fmax=-(FLT_MAX);
  for(int k=0; k<dst.rows; k++){
    for(int l=0; l<dst.cols; l++){
      float pixel=dst.at<unsigned char>(k,l);
      if (pixel > fmax)
          fmax=pixel;
      if (pixel < fmin)
          fmin=pixel;
    }
  }

  for(int m=0; m<dst.rows; m++){
    for(int n=0; n<dst.cols; n++){
      dst.at<unsigned char>(m,n)=(dst.at<unsigned char>(m,n)-fmin)*255.0/(fmax-fmin);
    }
  }
  */
}

試したこと

原画像の外のピクセルを参照していることへの対処やスケーリングなどを加えてみましたが、出力画像はめちゃくちゃのままでした

補足情報(言語/FW/ツール等のバージョンなど)

コンパイルにはMakefileを使用しています
ソースコードはこちら(問題のファイル名はkadaiC.cpp)

# Makefile template for building OpenCV programs in C
#  Usage: Change the TARGET to foo when compiling foo.c or foo.cpp

# Target program
TARGET=kadaiC

# Compiler
#CC=gcc
CC=g++

# Compiler options
CFLAGS=`pkg-config --cflags opencv` -O3
LDFLAGS=`pkg-config --libs opencv`

OBJS= $(TARGET).o
#OBJS= $(TARGET).o src1.o src2.o

# Default target
all: $(TARGET)

# Linking objects
$(TARGET): $(OBJS)
    $(CC) $(CFLAGS) $(LDFLAGS) -o $(TARGET) $(OBJS)

# Compile C source to objects
.c.o:
    $(CC) $(CFLAGS) -c $<

# Compile C++ source to objects
.cpp.o:
    $(CC) $(CFLAGS) -c $<

# Clean up for re-building
clean:
    rm *.o
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

0

sumが大きすぎてunsigned charに収まらないのではないでしょうか?
dst.at<unsigned char>(x,y)=sum;dst.at<unsigned char>(x,y) = sum / (maskW * maskH * 255);のようにもっと小さくしてやると変化はありますでしょうか。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/12/19 03:24

    回答ありがとうございます
    ご指摘の通りunsigned charの取り得る値の範囲を超えているのが原因でした。現状うまくいきましたので報告します。

    キャンセル

0

OpenCVに関しては全然わからないけど、わからないなりに気になった点を書いておきます。
・kernelとは何なのか。maskと書くべき所がkernelになってるのか、それともmaskとkernelには何か関係があるのか
・unsigned charにしているので、フィルターにマイナスの値が使えない。それで良いのか
・(既に指摘されてますが)sumの値はunsigned charの範囲外かもしれない。dstに入れる直前で if (sum < 0) sum = 0; else if (sum > 255) sum = 255; とでもやっておけば、その場しのぎかもしれないけど少しは改善されるかもしれない
・フィルターに変な値は入ってないか

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/12/19 03:27

    回答ありがとうございます
    maskとkernelは同じ意味で書いてますが、自分でもややこしい変数名で反省しております。お恥ずかしい限りです。
    フィルターにマイナスの値は今回は使わないので度外視していましたが、一般的ではありませんでした。ご忠告ありがとうございます。
    ご指摘の通り、sumの値がunsigned charの範囲を超えているのが原因でした。現状はうまくいきましたので報告します。

    キャンセル

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

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

関連した質問

  • 解決済

    byte配列のcv::Matへの画像変換

    byte配列に格納している画像データをMatに画像配列として保存します。この時、cv::imdecodeを使用しています。その後に画素値の変換をかけてcv::imencodeで再び

  • 解決済

    opencvでの画像の回転

    opencvを用いて読み込んだ画像の回転を行っています。 以下のプログラムで画像の回転を行い実行できたのですが、 画像が回転し、元の画像の場所が黒く表示されるのが気に入りません

  • 解決済

    途上opecvでの連続撮影

    opencvで静止画を30fpsで連続撮影を行いたいです。 現在は、使用しているカメラ(IMAGINGSOURCE社 産業用USB3.0カメラ)のIC Capture を使

  • 解決済

    opencv 動画 再生

    #include <stdio.h> #include <cv.h> #include <highgui.h> int main(int argc, char* argv[])

  • 解決済

    OpenCvSharp3で重心を求めたいです

    以下のように、ラベリングを実行するプログラムはできたのですが、ここから重心の座標や面積を求めるプログラムを作成したいです。どなたか、教えていただけますか? 最終的な目標としては

  • 解決済

    OpenCVを用いた物体検出

    現在OpenCV2.1を用いた上で顔検出にチャレンジしています。 学習等については問題なく行うことができ、顔の検出を行おうと思っているのですが、検出の段階で設定するパラメータの"m

  • 解決済

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

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

  • 解決済

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

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

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

  • C++

    2850questions

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

  • OpenCV

    794questions

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