![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?5a7ff87)
c言語で画像処理のソーベルのフィルタが作りたいのですが、どうにもうまく動きません。おかしい点をご指摘していただけないでしょうか。一次元配列で作りたいです。
/*wiは読み込んだ画素値、woは書き出す画素値、m1,m2はフィルタ係数、widthは画像の幅、heightは画像の高さ*/
void sobel(unsigned char wi[], unsigned char wo[], char m1[],char m2[],int width, int height){
int i,j,k,l,z;
unsigned char *w;
unsigned char *wo2;
w = (char*)malloc(sizeof(char)*(MW*MH));
wo2 = (char*)malloc(sizeof(char)*(MW*MH));
/*フィルタの適用*/
for(i=width+1; i<width*height; i++)
wo[i]=wi[i-1-width]*m1[0]+wi[i-width]*m1[1]+wi[i+1-width]*m1[2]+wi[i-1]*m1[3]+wi[i]*m1[4]+wi[i+1]*m1[5]+wi[i-1+width]*m1[6]+wi[i+width]*m1[7]+wi[i+1+width]*m1[8];
for(j=width+1; j<width*height; j++)
wo2[j]=wi[j-1-width]*m2[0]+wi[j-width]*m2[1]+wi[j+1-width]*m2[2]+wi[j-1]*m2[3]+wi[j]*m2[4]+wi[j+1]*m2[5]+wi[j-1+width]*m2[6]+wi[j+width]*m2[7]+wi[j+1+width]*m2[8];
for(k=width+1; k<width*height; k++)
wo[k] = (unsigned char)sqrt(wo[k]*wo[k]+wo2[k]*wo2[k]);
/*画素値を0から255に*/
for(l=width+1; l<width*height; l++){
if((unsigned char)wo[l] < 0)
w[l] = 0;
else if((unsigned char)wo[l] > 255)
w[l] = 255;
else
w[l] = wo[l];
}
for(z=width+1; z<width*height; z++)
wo[z] = w[z];
free(w);
free(wo2);
}
よろしくお願いしますm(_ _)m
No.1ベストアンサー
- 回答日時:
「どうにもうまく動きません」というのが、どう「うまく動かない」のかを説明していただけないと、
何に困っているのかこちらには分かりませんので、回答のしようがないのですが、
とりあえず見てわかる範囲で。
・各forループの範囲
ループを「i < width * height」といった条件で回していますが、
wi/wo のメモリ範囲が(画像サイズ)がwidth×heightなのだとしたら、範囲を超えてアクセスしており、これではメモリ破壊が起きます。
ループ範囲は、開始が0でなくwidth+1にしているのと同様に、終了条件を「i < width*(height-1)-1」にすべきでしょう。
・/*画素値を0から255に*/ の部分
ここで判定に使っている変数 wo は unsigned char 型の配列ですから、
その前のループ内のsqrt計算で結果が計算結果が0未満や255超になったときは、
unsigned char にキャストしてwo[k]に代入した時点で、その情報は失われてしまい、
データが壊れてしまってます。
その前段階の wo/wo2のループも含めて、計算処理内では、データはunsigned char 型ではなく、int型などで持っておくべきです。
あと、4回ループを回すのはかなり無駄です。一回のループ内で全て処理すれば十分。
メモリの一時確保も不要。
実際に動作は確認してませんが、
---ここから---
void sobel(unsigned char wi[], unsigned char wo[], char m1[],char m2[],int width, int height)
{
int i;
int w, w1, w2;
/*フィルタの適用*/
for(i=width+1; i<width*(height-1)-1; i++) {
w1=wi[i-1-width]*m1[0]+wi[i-width]*m1[1]+wi[i+1-width]*m1[2]+wi[i-1]*m1[3]+wi[i]*m1[4]+wi[i+1]*m1[5]+wi[i-1+width]*m1[6]+wi[i+width]*m1[7]+wi[i+1+width]*m1[8];
w2=wi[j-1-width]*m2[0]+wi[j-width]*m2[1]+wi[j+1-width]*m2[2]+wi[j-1]*m2[3]+wi[j]*m2[4]+wi[j+1]*m2[5]+wi[j-1+width]*m2[6]+wi[j+width]*m2[7]+wi[j+1+width]*m2[8];
w = (int)(0.5+sqrt(w1*w1+w2*w2));
if (w < 0) {
w = 0;
} else if (w > 255) {
w = 255;
}
wo[i] = (unsigned char)w;
}
}
---ここまで---
こんな感じのコードで十分なはずです。
お礼が遅れて申し訳ありません。
>>どうにもうまく動きません」というのが、どう「うまく動かない」のかを説明していただけないと、何に困っているのかこちらには分かりません
その通りですね。以後気を付けたいと思います。
指摘していただいた部分を直したら、ちゃんと動作しました。助かりました。丁寧なご解答、ありがとうございましたm(_ _)m
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# 並列プログラミングのπ計算について 1 2022/07/16 22:30
- Visual Basic(VBA) 【VBA】写真の貼り付けコードがうまく機能しません。 5 2022/09/01 18:43
- その他(プログラミング・Web制作) 物理の斜方投射で目盛りに数値を入れたい 2 2023/05/27 06:32
- その他(プログラミング・Web制作) Pythonにおける物理のシミュレーションでの単位変換について 2 2023/06/02 17:11
- その他(プログラミング・Web制作) Pythonによる物理の斜方投射の位置座標表示について 2 2023/06/05 12:46
- その他(プログラミング・Web制作) Pythonでのかんたんな物理シミュレーションについての書籍 5 2023/06/02 07:37
- その他(プログラミング・Web制作) 物理の斜方投射の目盛り線とx軸、y軸の追加について 3 2023/05/26 21:11
- HTML・CSS cssが効かなくて困ってます 1 2023/01/01 23:57
- PHP 共通の処理をまとめる方法がわからないのでアドバイスお願いします。 1 2022/12/19 20:20
- その他(プログラミング・Web制作) ボールの動きがスムーズに動いてかつ目盛り線描画を維持するためには 4 2023/05/31 10:01
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
fgetsなどのときのstdinのバッ...
-
DPマッチング
-
C言語のfor文です。 繰り返しの...
-
配列をnビットシフトする
-
double型の値をchar配列に変換...
-
2曲同時再生するにはどうした...
-
'const char *' 型は 'char *' ...
-
switch文で文字を比較すること...
-
char型からのバイト数取得
-
文字列から空白を取り除きたい...
-
間接操作のレベルとは
-
C言語のポインターで詰まっている
-
絶対パスからのファイル名の切...
-
文字列の中のカンマを消したい
-
javaでunsignedは使えないので...
-
charからLPTSTRへの変換方法
-
C言語の入力した文字を反転させ...
-
AnsiPos相当の関数はありません...
-
構造体の各メンバにfor文からア...
-
c++ 文字列を入力して、一文字...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
fgetsなどのときのstdinのバッ...
-
C言語のfor文です。 繰り返しの...
-
文字列から空白を取り除きたい...
-
charからLPTSTRへの変換方法
-
charでの計算?
-
配列をnビットシフトする
-
CStringをwchar_tに変換したい
-
c++ 文字列を入力して、一文字...
-
str系関数を使わずに二つの文字...
-
間接操作のレベルとは
-
int main()の・・・
-
C言語の入力した文字を反転させ...
-
atoi( ) の反対をやりたい
-
switch文で文字を比較すること...
-
テキストデータをそのままバイ...
-
Win32APIでのエディットボック...
-
double型の値をchar配列に変換...
-
干支のプログラム
-
コンパイルエラー invalid ope...
-
間接参照のレベルが異なっています
おすすめ情報