• 締切済み

JavaScriptでソーベルフィルタを実装したい

ソーベルフィルタをJavaScriptで作成したいと思っています。 まずは縦方にフィルタしたいと思い下記のコードを書きました。 ですが思い通りに処理が行われません。 画像により異なりますがフィルタ処理した画像は 多くの部分が#FF00FFで塗りつぶされてしまいます。 canvasImageData = cxt.getImageData(0, 0, canvas.width, canvas.height); for (i = 1; i < canvasImageData.width - 1; i++) { for (j = 1 ; j < canvasImageData.width - 1; j++) { sumRed = sumGreen = sumBlue = 0; k = (j * 4) + i * canvasImageData.width * 4; for (l = -1; l <= 1; l++) { for (m = -1; m <= 1; m++) { n = (k + m) + l * canvas.width * 4; sumRed += canvasImageData.data[n] * filter[l + 1][m + 1]; sumGreen += canvasImageData.data[n + 1] * filter[l + 1][m + 1]; sumBlue += canvasImageData.data[n + 2] * filter[l + 1][m + 1]; } } sumRed = Math.floor(Math.sqrt(Math.pow(sumRed, 2))); sumGreen = Math.floor(Math.sqrt(Math.pow(sumGreen, 2))); sumBlue = Math.floor(Math.sqrt(Math.pow(sumBlue, 2))); sumRed = (sumRed > 255) ? 255 : sumRed; sumGreen = (sumGreen > 255) ? 255 : sumGreen; sumRed = (sumBlue > 255) ? 255 : sumBlue; canvasImageData.data[k] = sumRed; canvasImageData.data[k + 1] = sumGreen; canvasImageData.data[k + 2] = sumBlue; } } cxt.putImageData(canvasImageData, 0, 0, canvasImageData.width, canvas.height); 色々試したのですが手がかりがありません。 どのようなことでも良いので教えていただきたいと思います。

みんなの回答

noname#208507
noname#208507
回答No.2

JavaScriptをよく知らないのでコードからの推測ですが、0から255ではエッジ強度を記録するのに足りないのでは。フィルタの中央だけでも元の輝度が255と0だった場合 sqrt((255 * (-2) - 0 * 2)^2) = 510 になると思います。

sh_200911
質問者

お礼

ご解答ありがとうございます。 >sqrt((255 * (-2) - 0 * 2)^2) = 510 ご指摘の部分を調べたら幾つか情報がありました。 まだ解決の方法には至っていませんが手がかりができました。 ありがとうございます。

全文を見る
すると、全ての回答が全文表示されます。
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.1

・filter[][]の中身は?

sh_200911
質問者

補足

コードが足りなくて申し訳ありません。 filterは下記のように定義しました。 var filter = []; filter[0] = [-1, 0 ,1]; filter[1] = [-2, 0, 2]; filter[2] = [-1, 0, 1]; 宜しくお願いいたします。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • c言語でソーベルフィルタが作りたい

    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

  • 実行すると if文 に矛盾

    #include <stdio.h> #include <math.h> int main(void) { /* */ double c, l, m, n, w=1, x[4]={1,2,3,4}, y[4]={1,2,3,4}; /* */ int j, k, u, v; /* */ for(j=0; j<3; j++){ /*   */ for(k=j+1; k<4; k++){ /*     */ l = sqrt( pow(x[j]-x[k], 2) + pow(y[j]-y[k], 2) ); /*     */ m = sqrt( pow(x[j], 2) + pow(y[j], 2) ); /*     */ n = sqrt( pow(x[k], 2) + pow(y[k], 2) ); /*     */ c = ( pow(m, 2) + pow(n, 2) - pow(l, 2) ) / (2*m*n); /*☆    */ /* if(c=w) ; */ /*※    */ if(c<=w){ /*       */ w = c; /*       */ u = j; /*       */ v = k; /*●    */ } else if(c>w){ /*       */ if(c=w) /*         */ printf("no way\n"); /*     */ } /*   */ } /* */ } /* */ printf("[ P%d P%d ]\n", u, v); /* */ return(0); } -------------------------------------------------------------------------------- 上記プログラムなのですが、Visual C++ でこれを実行すると、 ------------------------------ no way no way no way no way [ P0 P2 ] Press any key to continue ------------------------------ と出力されてしまいました。 ☆行のif文のコメントを外して直前で c=w を評価すると、※の部分が正常に処理されました。 なぜこのような矛盾が生じているのでしょうか? 何かご意見いただければ幸いです。 ※今回 Visual C++ でしか実行できるものがなかったため、他では確認できておりません。恐縮です。 ※この投稿の文字量の制限のため、プログラムの解説は割愛しました; ※補足などでお伝えできればよいのですが…。

  • FFTのソースについて

    512個のデータに対してFFTをかけ、変換後の絶対値を得たいのですが矢印の部分でプログラムがとまり、特にエラーメッセージも出ません。 原因がわかりません。申し訳ありませんが、よろしくお願いします。 void FFT(int x[], int y[]) {    int d, dn, pow, m, j1, j2, exp2, j , k, ndv2, t, flags= 1;    int n_data = 0, dnumb = 512, nf, jk;    double w, arg, c, s, t1, t2, t0, dt, ana, anb, answer;    double [] xr = new double[512];    double [] xi = new double[512]; dn=dnumb; w=6.283185303/dnumb; pow=exp2(dnumb); *2の何乗かを計算するメソッドです for(t = 0; t < 512; t++){ if(t < 500) xr[t] = x[t]; else xr[t] = xr[499]; xi[t] = 0; } for(int i=1; i<=pow ; i++) { m=dn; dn=dn/2; arg=0; for(int j=1; j<=dn; j++) { c=Math.cos(arg); s=-flags*Math.sin(arg); arg=arg+w; k=m; while(k<=dnumb) { j1=k-m+j; j2=j1+dn; →→→→→→→  t1=xr[j1]-xr[j2]; t2=xi[j1]-xi[j2]; xr[j1]=xr[j1]+xr[j2]; xi[j1]=xi[j1]+xi[j2]; xr[j2]=c*t1+s*t2; xi[j2]=c*t2-s*t1; k=k+m; } } w=2*w; } j=1; ndv2=dnumb/2; for(int i=1; i<=(dnumb-1); i++) { if(i<j) { t1=xr[j]; t2=xi[j]; xr[j]=xr[i]; xi[j]=xi[i]; xr[i]=t1; xi[i]=t2; } k=ndv2; while(k<j) { j=j-k; k=k/2; } j=j+k; } for(t = 0; t < 512; t++){ ana = Math.pow(xr[t], 2); anb = Math.pow(xi[t], 2); answer = Math.pow(ana + anb, 0.5); } if (flags==1) { for(int j=1; j<=dnumb; j++) { xr[j]=xr[j]/dnumb; xi[j]=xi[j]/dnumb; } } }

    • ベストアンサー
    • Java
  • このソースコードについて

    AOJにてこのコードを提出したところTime Limit Exceededでドロップされました。 Visual studio 2013 で動かしたところ特に怪しい挙動や間違いを出力することはなかったのですが。。。 ちなみに言語はC++です。 問題のURL http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0056 #include<iostream> #include<math.h> using namespace std; int p[20000],d; void primefinder(int a){ p[0] = 2; int k, l = 0; for (int i = 3; i <= a; i++){ k = (int)sqrt(i); for (int j = 2; j <= k + 1; j++){ if (j == k + 1){ p[++l] = i;} else if (i%j == 0)break; } } d = l + 1; } int main(){ int n,m,q,count; while ((cin >> n), n){ count = 0; m = n / 2; primefinder(m); for (int i = 0; i < d; i++){ q = n - p[i]; if (q <= 1)continue; for (int j = 2; j <= (int)sqrt(q)+1; j++){ if (j == (int)sqrt(q) + 1)count++; else if (q%j == 0)break; } } cout << count << endl; } }

  • FCC(面心立方)の位置に粒子を配置する方法

    main関数の中で以下のように書きました.よりよくするにはどうすればいいでしょうか.(計算速度,見た目) i=0; for(j=0;j<M;++j){ for(k=0;k<M;++k){ for(l=0;l<M;++l){ if(i<M*M*M){ rx[i]=0.01+0.5*L+a*(j-M/2); ry[i]=0.01+0.5*L+a*(k-M/2); rz[i]=0.01+0.5*L+a*(l-M/2); } ++i; } } } for(j=0;j<M;++j){ for(k=0;k<M;++k){ for(l=0;l<M;++l){ if(i<2*M*M*M){ rx[i]=0.01+0.5*L+a*(j-M/2)+a/2; ry[i]=0.01+0.5*L+a*(k-M/2)+a/2; rz[i]=0.01+0.5*L+a*(l-M/2); } ++i; } } } for(j=0;j<M;++j){ for(k=0;k<M;++k){ for(l=0;l<M;++l){ if(i<3*M*M*M){ rx[i]=0.01+0.5*L+a*(j-M/2)+a/2; ry[i]=0.01+0.5*L+a*(k-M/2); rz[i]=0.01+0.5*L+a*(l-M/2)+a/2; } ++i; } } } for(j=0;j<M;++j){ for(k=0;k<M;++k){ for(l=0;l<M;++l){ if(i<4*M*M*M){ rx[i]=0.01+0.5*L+a*(j-M/2); ry[i]=0.01+0.5*L+a*(k-M/2)+a/2; rz[i]=0.01+0.5*L+a*(l-M/2)+a/2; } ++i; } } }

  • RGBをCMYKに変換するプログラム

    Windows7 VS2008 SP1 RGBからCMYKに変換するプログラムを以下の様に書いている ([詳解]画像処理プログラミング という本に載っている ソースです) のですがうまくいきません。 おそらく型の扱い??だと思うのですが・・ 具体的にどの部分を修正すればいいのかご指摘お願いします。 INPUT:24bpp raw int RawToCMYK(WCHAR *filename,int width,int height) { FILE *fpt; FILE *fpt_C,*fpt_M,*fpt_Y,*fpt_K; unsigned char *layer; unsigned char *C,*M,*Y,*K; int i,j; _wfopen_s(&fpt,filename,L"rb"); if(fpt==0x00) { MessageBox(NULL,L"RawToCMYK Error",L"RawToCMYK Error",MB_OK); return -1; } else { layer=(unsigned char*)malloc(3*width*height); C=(unsigned char *)malloc(width*height); M=(unsigned char *)malloc(width*height); Y=(unsigned char *)malloc(width*height); K=(unsigned char *)malloc(width*height); fread(&layer[0],sizeof(unsigned char),3*width*height,fpt); fclose(fpt); _wfopen_s(&fpt_C,L"RawToC.raw",L"wb"); _wfopen_s(&fpt_M,L"RawToM.raw",L"wb"); _wfopen_s(&fpt_Y,L"RawToY.raw",L"wb"); _wfopen_s(&fpt_K,L"RawToK.raw",L"wb"); for(i=0;i<3*width*height;i+=3*width) { for(j=0;j<3*width;j+=3) { C[i/3+j/3]=255-layer[i+j]; M[i/3+j/3]=255-layer[i+j+1]; Y[i/3+j/3]=255-layer[i+j+2]; K[i/3+j/3]=min3(C[i/3+j/3],M[i/3+j/3],Y[i/3+j/3]); if(K[i/3+j/3]==0xff) { C[i/3+j/3]=0x00; M[i/3+j/3]=0x00; Y[i/3+j/3]=0x00; } else { C[i/3+j/3]=(C[i/3+j/3]-K[i/3+j/3])*255/(255-K[i/3+j/3]); M[i/3+j/3]=(M[i/3+j/3]-K[i/3+j/3])*255/(255-K[i/3+j/3]); Y[i/3+j/3]=(Y[i/3+j/3]-K[i/3+j/3])*255/(255-K[i/3+j/3]); } } } fwrite(&C[0],sizeof(unsigned char),width*height,fpt_C); fwrite(&M[0],sizeof(unsigned char),width*height,fpt_M); fwrite(&Y[0],sizeof(unsigned char),width*height,fpt_Y); fwrite(&K[0],sizeof(unsigned char),width*height,fpt_K); fclose(fpt_C); fclose(fpt_M); fclose(fpt_Y); fclose(fpt_K); free(C); free(M); free(Y); free(K); return 0;

  • JavaScriptについて

    本を読みながら勉強しているのですが解説が乗っていなくてわからない部分があるので教えてください <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,user-scalable=yes,initial-scale=1.0,maximum-scale=3.0"> <script src="plugins/plugin-loader.js"></script> <link rel="stylesheet" href="plugins/plugin-loader.css"> </head> <body> <canvas id="canvas" width="300" height="300"></canvas> <script> var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); //ランダムに50個多角形の表示 for (var i = 0; i < 50; i++) { randomDraw(); } //指定範囲のランダムな整数を返す関数 function randomI(nFrom,nTo) { var f = nTo - nFrom + 1; return Math.floor(Math.random() * f) + nFrom; } //ランダムに多角形を描画する関数 function randomDraw() { //パス指定 ctx.beginPath(); //点をランダムに決定 var n = randomI(2,7); ctx.moveTo(randomI(0,canvas.width),randomI(0,canvas.hright)); for (var i = 0; i < n; i++) { ctx.lineTo(randomI(0,canvas.width),randomI(0,canvas.height)); } ctx.closePath(); //描画 ctx.fillStyle = "#" + randomI(0,0xFFFFFF).toString(16); ctx.fill(); } </script> </body> </html> というコードでランダムに50個多角形を描画するというものです function randomI(nFrom,nTo) { var f = nTo - nFrom + 1; return Math.floor(Math.random() * f) + nFrom; ここのrandomIとnToとnFromというのは変数名ですか?これはいったい何者ですか? var n = randomI(2,7); ここの数字を変更すると何かが変わるのですがうまく言葉にできません 何がどう変わるのか教えてください

  • FFTをc言語でプログラミング

    助けてください↓c言語でFFTをプログラミングしているのですがバグが発見できずに困り果て居ます。 プログラミングは以下の通りです。画像はカラーではなく、グレースケールのMANDRILLに対して行っています。 for(n=0;n<M;n++){    for(i=0;i<N;i++){ for(j=0;j<N;j++){ Imbatx[n][i][j]=0; } } } //行FFT //まずはソート for(i=0;i<N;i++){ int x=1; for(j=0;j<N;j++){ if(j<N/2){        //左半分 if(j%2!=0) //jが奇数 batx[0][i][j]=imagein[i][j+N/2-1]; if(j%2==0) //jが偶数 batx[0][i][j]=imagein[i][j]; } if(N/2<=j && j<N){ //右半分 if(j%2!=0) //jが奇数 batx[0][i][j]=imagein[i][x+N/2-1];      if(j%2==0) //jが偶数 batx[0][i][j]=imagein[i][x]; x++; } } } for(i=0;i<N;i++){ for(n=1;n<M+1;n++){ k=0; for(j=0;j<N;j++){ mul=(int)pow(2.0,(double)n); if(j%mul < mul/2){ //偶数列 batx[n][i][j] = batx[n-1][i][j]+cos(2*PI*k/mul)*batx[n-1][i][j+mul/2]- sin(2*PI*k/mul)*Imbatx[n-1][i][j+mul/2]; Imbatx[n][i][j]=Imbatx[n-1][i][j]+sin(2*PI*k/mul)*batx[n-1][i][j+mul/2]+ cos(2*PI*k/mul)*Imbatx[n-1][i][j+mul/2]; k++; } else{ //奇数列 batx[n][i][j] = cos(2*PI*k/mul)*batx[n-1][i][j] + batx[n-1][i][j-mul/2]- sin(2*PI*k/mul)*Imbatx[n-1][i][j]; Imbatx[n][i][j]=Imbatx[n-1][i][j-mul/2]+sin(2*PI*k/mul)*batx[n-1][i][j]+cos(2*PI*k/mul)*Imbatx[n-1][i][j]; k++; } Re_countx[i][j] = batx[M][i][j]; Im_countx[i][j] = Imbatx[M][i][j]; } } } for(i=0;i<N;i++){ for(j=0;j<N;j++){ FFT[i][j]=pow(pow(Re_countx[i][j],2)+pow(Im_countx[i][j],2),0.5); FFT[i][j]=log10(FFT[i][j]); if(FFT[i][j]>max) max=FFT[i][j]; imageout[i][j]=(unsigned char)255*FFT[i][j]/max; } } 結果的に出力される画像は以下の画像になります。 ごらんのように縞模様が出てしまいます。 分かる方どうかお願いいたします。

  • お願いします。m(><)m

    つい最近Javaのプログラミングを大学ではじめたものなんですが、 次のような課題を出されたのですが全然わからないため困っており・・・ どなたか分かる方ぜひ教えていただけないでしょうか?m(><)m 3.次のプログラムは何を行うプログラムか.簡単に説明しなさい.また, 結果を得るまでに,A[k]==aの比較が行われた回数を書きなさい. A=new Array(3, 8, 19, 20, 22, 24, 45); i=0; j=A.length-1; a=19; k=Math.floor((i+j)/2); while(i<=j){ if(A[k] == a){ break; } else if(A[k] > a){ j = k - 1; } else{ i = k + 1; } k = Math.floor((i+j)/2); } if(i>j) k=-1; document.write(a," ",k);

  • JavaScriptの問題に関して教えてください。

    下記問題の解き方および答えが考えても全然分からず、お教えいただきたいです。お願いいたします。 以下のプログラムを読んで、どういったプログラムなのかを説明してください。 let change = 0; let change_sum = 0; const data = [ 31, 41, 59, 26, 53, 58, 97, 93, 23, 84 ]; console.log("並べ替える前"); for (let i = 0; i < data.length; i++) { console.log(data[i] + " "); }// for console.log("\n"); console.log("***********************************"); console.log(""); for (let i = 0; i < data.length - 1; i++) { for (let j = i + 1; j < data.length; j++) { if (data[i] > data[j]) { let a = data[i]; data[i] = data[j]; data[j] = a; change++; }// if }// for(内側1) console.log((i + 1) + "回目"); console.log(`${change}回`); for (let k = 0; k < data.length; k++) { process.stdout.write(data[k] + " "); }// for(内側2) console.log("\n"); change_sum += change; change = 0; }// for(外側) //最終結果の表示 console.log("***********************************"); console.log(""); console.log(`${change_sum}回`); console.log("最終結果"); for (let i = 0; i < data.length; i++) { process.stdout.write(data[i] + " "); }// for console.log("");