• ベストアンサー

平滑化フィルタ

今、平滑化フィルタを作っています。 下記のようなプログラムであっているのでしょうか? #include<stdio.h> #include<stdlib.h> #include<limits.h> #include "basic_data_struct.h" //関数宣言 unsigned short **us_Calloc1(int width,int height); void filter(imginfo *img) { int box[9]={1,1,1,1,1,1,1,1,1}; //単純平均化 int weight[9]={0}; int i=0,j=0,y,x; //ループ変数 double div_const=9.0; int height,width; height=img->height; //高さ width=img->width; //幅 int sum=0;     //合計 unsigned short result=0; //結果 img->data2=us_Calloc1(width,height); //結果を入れる配列を動的に確保(2次元) for(i=1; i<height-1; i++) for(j=1; j<width-1; j++){ box[0]=img->data[i-1][j-1]; box[1]=img->data[i-1][j]; box[2]=img->data[i-1][j+1]; box[3]=img->data[i][j-1]; box[4]=img->data[i][j]; box[5]=img->data[i][j+1]; box[6]=img->data[i+1][j-1]; box[7]=img->data[i+1][j]; box[8]=img->data[i+1][j+1]; sum=(box[0]*weight[0]+box[1]*weight[1]+box[2]*weight[2] +box[3]*weight[3]+box[4]*weight[4]+box[5]*weight[5] +box[6]*weight[6]+box[7]*weight[7]+box[8]*weight[8]); //printf("sum=%d\n",sum); result=(sum/(3*3)); //3*3近傍 img->data2[i-1][j-1]=(unsigned short)result; //結果の代入 //printf("img->data[%d][%d]=%d\n",i,j,img->data[i][j]); } } もっと、効率のよい書き方があれば、アドバイスよろしく おねがいします。できればサンプルコードをかいていただければ ありがたいです。

質問者が選んだベストアンサー

  • ベストアンサー
  • yama5140
  • ベストアンサー率54% (136/250)
回答No.4

>今、平滑化フィルタを作っています。 >下記のようなプログラムであっているのでしょうか? (「ような」を「考え方の」としてアドバイス)  ダミーデータで試行してみては・・。    iDummy[3][3] = { { 1, 2, 3 }, { 10, 20, 30 }, { 1, 2, 3 } };    img->data を iDummy に置換して。        もちろん、3 * 3 で割っているのだから、weight[] の計(◆)は 9 にして。     >result=(sum/(3*3)); //3*3近傍  もしかして、3*3 は、誤解されてませんか(◆)。 >もっと、効率のよい書き方があれば、アドバイスよろしくおねがいします。  ちょっと見、    sum=(box[0]*weight[0]+box[1]*weight[1]+box[2]*weight[2]  +box[3]*weight[3]+box[4]*weight[4]+box[5]*weight[5]  +box[6]*weight[6]+box[7]*weight[7]+box[8]*weight[8]); の部分は、  sum = box[ 0 ] * weight[ 0 ];  sum += box[ 1 ] * weight[ 1 ];  sum += box[ 2 ] * weight[ 2 ];  sum += box[ 3 ] * weight[ 3 ];  sum += box[ 4 ] * weight[ 4 ];  sum += box[ 5 ] * weight[ 5 ];  sum += box[ 6 ] * weight[ 6 ];  sum += box[ 7 ] * weight[ 7 ];  sum += box[ 8 ] * weight[ 8 ];   とできます、ということは、・・。  for( sum = 0, k = 0; k < 9; k++ ) sum += ( box[ k ] * weight[ k ] ); ------------------------------------------ ( No.3 さんへの補足ソース) >このように訂正したのですがうまくできません・・・ ★ weight[] の総計(◆)で割らないなんて・・。  まさか、box[] が「加重」じゃあないよね・・。  ならば、「うまく」できるハズ?だから。 蛇足  当たり前ですが、weight[] の総計を 1.0 とすれば、割らなくてすみます・・。

ultrabanan
質問者

お礼

ご回答ありがとうございます.

その他の回答 (3)

回答No.3

 何度も申し訳ない。 訂正 data[i + k / 3][j + k % 3]->data[i + d[k / 3]][j + d[k % 3]]

ultrabanan
質問者

補足

void filter(imginfo *img) { int box[9]={1,1,1,1,1,1,1,1,1}; int weight[9]={0}; int i=0,j=0; double div_const=9.0; int height,width; int sum=0; unsigned short result=0; height=img->height; width=img->width; img->data2=us_Calloc1(width,height); printf("img->dataのデータをimg->data2に移すことができました.\n"); for(i=1; i<height-1; i++) for(j=1; j<width-1; j++){ weight[0]=img->data[i-1][j-1]; weight[1]=img->data[i-1][j]; weight[2]=img->data[i-1][j+1]; weight[3]=img->data[i][j-1]; weight[4]=img->data[i][j]; weight[5]=img->data[i][j+1]; weight[6]=img->data[i+1][j-1]; weight[7]=img->data[i+1][j]; weight[8]=img->data[i+1][j+1]; sum=(box[0]*weight[0]+box[1]*weight[1]+box[2]*weight[2] +box[3]*weight[3]+box[4]*weight[4]+box[5]*weight[5] +box[6]*weight[6]+box[7]*weight[7]+box[8]*weight[8]); result=(unsigned short)(sum/(3*3)); img->data2[i][j]=(unsigned short)result; sum=0; result=0; } } このように訂正したのですがうまくできません・・・

回答No.2

>"sum"が宣言時しか初期化されていないし  "sum"が宣言時しか0クリアーされていないし

回答No.1

 {}の対応が取れてないし、"sum"が宣言時しか初期化されていないし、 何をもって"効率のよい書き方"とするのか判らないけど、 こんなのはどうでしょう。 int d[3] = {-1, 0, 1}; int k; ・・・ for(k = 0; k < 9; k ++) box[k] = data[i + k / 3][j + k % 3]; for(k = 0; k < 9; k ++) sum += box[k] * weight[k];

関連するQ&A

  • raw形式からbmp形式への書き込み (画像処理)

    今、raw形式のファイルを読み込んで、bmp形式への書き込みを 行うプログラムを作成しているのですがうまくいきません. 作成したプログラムの一部は以下のようになっています. ------------------rawファイルを読み込む関数の一部------------- //1次元配列の確保 tmp=us_Calloc2(width,height); //画像の読み込み fread(tmp,sizeof(unsigned short),width*height,fp); //2次元配列の確保 img->data=us_Calloc1(width,height); //1次元配列から2次元配列にデータを移動する for(i=0; i<height; i++){ for(j=0; j<width; j++){ img->data[i][j]=tmp[(width*i)+j]; } } ------------------------------------------------------------ --------------bmpファイルに書きこむ(一部)-------------- //bufのメモリ領域の確保 buf=us_Calloc2(width,height); for(i=0; i<height; i++){ for(j=0; j<width; j++){ buf[(width*i)+j]=img->data[i][j]; } } //BMPのファイルヘッダーの出力(省略) //BMPの情報ヘッダーの出力(省略) //画像データの出力 if(fwrite(buf,sizeof(unsigned short),size,fp)!=size){ printf("画像をBMPに書き込むことができませんでした.\n"); free(buf); fclose(fp); exit(-1); } } このように書いたのですが、うまくBMPファイルに出力できません. アドバイスよろしくお願いします.

  • 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

  • C言語についてです。

    EXELEファイルから値を読みこんで、各自のBMIと全体の身長・体重の平均値を求めるプログラムを作成したいんですが…C言語で…。途中までで混乱してしまい、あっているかも分からないのでお願いしたいです。よろしくお願いします。ヒントだけでもありがたいです。 下がそのファイルです。 height weight 170.7 52.9 166.8 71.3 171.4 58.5 173.4 76.7 176.1 80.2 184 89.1 179 64.7 177.2 78.5 177.7 80.7 173.8 64 167.7 60.3 181.6 72.3 162.4 53 177.4 69.6 178 76.4 174 77.2 185.4 86 172 68.5 172.7 60 166.5 62 171.3 69.6 177 79 174.8 82.6 167.5 69.2 176.8 80.1 181.5 76 177.3 76.4 169.4 51.8 165.2 73.2 175.3 72.3 181.5 72.4 171.5 68.8 176 73.2 186 99.8 167.3 65.5 176.1 78 183.3 77.2 177.5 59.5 180.3 62 171.2 74.7 175 87.2 176 80 171.8 50.6 平均身長の値を出すプログラムは出ているので…これもあわせてBMIと平均体重出してくれるとうれしいです。 /* basic claculation */ #include <stdio.h> #include <math.h> int main(void) { int i, ii; int ntotal; double sum_height; double weight[50], height[50]; double mean_height; char w[6],h[6]; FILE *fp; /* initial setting */ /* ntotal: total word number */ /* sum : total character number */ ntotal = 0; sum_height = 0; /* file open */ /* my data file is weight-height.data */ /* which is in my root directory */ fp = fopen("./weight-height.data","r"); /* skip character reading. */ fscanf(fp,"%s,%s",w,h); /* ntotal: total number */ /* sum : total value */ for (i=0;i<=47;i++) { if (feof(fp)) break; fscanf(fp,"%lf,%lf",&weight[i],&height[i]); printf(" weight = %lf height = %lf \n",weight[i],height[i]); sum_height = sum_height + height[i]; } fclose(fp); ntotal = i; printf(" 全人数 = %d \n",ntotal); mean_height = sum_height /ntotal; printf(", 平均身長 = %lf \n",mean_height); return(0); }

  • 画像処理プログラム

    プログラムどう改良していいか全然わかりません 教えてください Sobel フィルタは垂直成分しか見ていないため、エッジ検出としては不十分である。任 意方向のエッジを検出するためには、図4 のような垂直方向と水平方向のオペレータを用いて各成分を抽出し、それらを合成する必要がある(図5 参照)。そこで、プログラムを次のように改良し、全方向のエッジに対応したプログラムにする。 <変更前> <変更後> c =1 􀀀2 􀀀1      cy=-1 -2 -1   cx=-1 0 1 0 0 0    →     0 0 0     -2 0 2 1 2 1          1 2 1     -1 0 1 畳み込み演算     畳み込み演算 L = c・img   →  Ly = cy・img, Lx = cx・img エッジの強さ     エッジの強さ |L|        → |L|=√Lx^2+Ly^2 /** Sobel.c **/ #include <stdio.h> #include <stdlib.h> #define V_width 320 #define V_height 240 #define amp 1.0 int d[9]; int i, j, dat; float L; unsigned char img [V_height][V_width]; /* input image */ unsigned char work[V_height][V_width]={0}; /* work space */ /******* filter coefficients *******/ static int c[9] = {-1, -2, -1, 0, 0, 0, 1, 2, 1}; /*************************************/ int main(int argc, char *argv[]) { FILE *fpi, *fpo; unsigned char data; char str[256]; int width, height; /* check arg number */ if (argc != 3) { fprintf(stderr, "Usage: %s [input] [output]\n", argv[0]); exit(1); } /* open input file */ if ((fpi = fopen(argv[1], "rb")) == NULL) { fprintf(stderr, "input file open error!\n"); exit(1); } /* open output file */ if ((fpo = fopen(argv[2], "wb")) == NULL) { fprintf(stderr, "output file open error!\n"); exit(1); } /* read PGM header */ while(1){ fgets(str, 256, fpi); if(str[0] == '#'){ fprintf( stderr, "%s", str); } else if( !strncmp( str, "P5", 2)){ fprintf( stderr, "This file is a PGM file.\n"); } else if( !strncmp( str, "255", 3)){ fprintf( stderr, "The file is opened.\n"); break; } else{ sscanf( str, "%d %d", &width, &height); fprintf( stderr, "SIZE: %3d x %3d\n", width, height); } } /* read data */ for (i=0; i<height; i++) { for (j=0; j<width; j++) { fread( &data, 1, 1, fpi); img[i][j] = data; } } /* image processing */ for (i=1; i < height-1; i++) { for (j=1; j < width-1; j++) { d[0]=img[i-1][j-1]; d[1]=img[i-1][j]; d[2]=img[i-1][j+1]; d[3]=img[i][j-1]; d[4]=img[i][j]; d[5]=img[i][j+1]; d[6]=img[i+1][j-1]; d[7]=img[i+1][j]; d[8]=img[i+1][j+1]; L = (float)(c[0]*d[0] + c[1]*d[1] + c[2]*d[2] + c[3]*d[3] + c[4]*d[4] + c[5]*d[5] + c[6]*d[6] + c[7]*d[7] + c[8]*d[8]); L = amp*L; dat = (int)(L); if (dat < 0) dat = -dat; if (dat > 255) dat = 255; work[i][j] = (unsigned char)dat; } } /* write data */ fprintf(fpo,"P5\n %d %d\n 255\n", width, height); for (i= 0; i<height; i++) { for (j= 0; j<width; j++) { fwrite( &work[i][j], 1, 1, fpo); } } fclose(fpi); fclose(fpo); return 0; }

  • C言語のプログラミングの解答例又は修正箇所をおしえていただきたいのですが

    #include <stdio.h> int main(int argc, char **argv){ int a,b,c,g,r,i,j,ll;  int blue,green,red;  FILE *fpi,*fpo; unsigned long size,head,width,height,offset;  unsigned long comp,isize,ucolor,icolor; unsigned short plane,bitsize;  unsigned long wreso,hreso; unsigned char *image;  char infile[1024] = "t.bmp";  char outfile[1024] = "g.bmp"; long ww,hh;  long w3,h3;  unsigned char *img;  unsigned char *img2; int bai1,bai2;  bai1=1,bai2=3; fpi=fopen(infile,”rb"); for(i=0;i<2;i++){c=getc(fpi);} for(i=0,size=0;i<4;i++){size += (getc(fpi))<<(8*i);} for(i=0;i<4;i++){c=getc(fpi);} for(i=0,offset=0;i<4;i++){offset += (getc(fpi))<<(8*i);} ↑と同じようhead,width,height,plane,bitsize,comp,isize,wreso,hreso,ucolor,icolorを書く(ただしplane,bitsizeはi<2) hh=height*bai1/bai2; ww=width *bai1/bai2; img2 = (unsigned char*)malloc(sizeof(char)*3*ww*hh); for(j=0;j<hh;j++){ for(i=0;i<ww;i++){ int i1,j1,i2,j2; double x,pa,pb,pc,pd,x11,x21,x12,x22; int bb,gg,rr; i1=(i*(width-1))/(ww-1); i2=i1+1; x=(i*(width-1)*1.0)/((double)(ww-1)); pa=x-i1; pb=i2-x; j1=(j*(height-1))/(hh-1); j2=j1+1; x=(j*(height-1)*1.0)/((double)(hh-1)); pc=x-j1; pd=j2-x; x11=(double)img[j1*width*3+i1*3+0;] x21=(double)img[j1*width*3+i2*3+0]; x12=(double)img[j2*width*3+i1*3+0]; x22=(double)img[j2*width*3+i2*3+0]; bb=(((x11*pb+x21*pa)/(pa+pb))*pd+((x12*pb+x22*pa)/(pa+pb))*pc)/(pc+pd); x11=(double)img[j1*width*3+i1*3+1]; x21=(double)img[j1*width*3+i2*3+1]; x12=(double)img[j2*width*3+i1*3+1]; x22=(double)img[j2*width*3+i2*3+1]; gg=(((x11*pb+x21*pa)/(pa+pb))*pd+((x12*pb+x22*pa)/(pa+pb))*pc)/(pc+pd); x11=(double)img[j1*width*3+i1*3+2]; x21=(double)img[j1*width*3+i2*3+2]; x12=(double)img[j2*width*3+i1*3+2]; x22=(double)img[j2*width*3+i2*3+2]; rr=(((x11*pb+x21*pa)/(pa+pb))*pd+((x12*pb+x22*pa)/(pa+pb))*pc)/(pc+pd);; img2[j*ww*3+i*3+0]=(unsigned char)(bb&0xff); img2[j*ww*3+i*3+1]=(unsigned char)(gg&0xff); img2[j*ww*3+i*3+2]=(unsigned char)(rr&0xff); } } w3=ww*3; h3=hh*3; if((w3*3)%4==0){size=offset+w3*h3*3;} else{size= offset+w3*h3*3-(4-(w3*3)%4);} isize = size-offset; fpo=fopen(outfile,"wb"); putc('B', fpo); putc('M', fpo); for(i=0;i<4;i++){putc(((size>>(8*i))&0xff),fpo);} for(i=0;i<4;i++){putc(0x0,fpo);} for(i=0;i<4;i++){putc((((offset)>>(8*i)&0xff),fpo);} ↑と同じようhead,width,height,plane,bitsize,comp,isize,wreso,hreso,ucolor,icolorを書く(ただしplane,bitsizeはi<2) fwrite(&w3 ,sizeof(long),1,fpo); ↑と同じように&h,&offset,&head,&width,&height,&plane,&bitsize,&comp,&isize,&wreso,&hreso,&ucolor,&icolorを書く for(jj=0;jj<3;jj++){ for(j=hh-1;j>=0;j--){ ll=0; for(ii=0;ii<3;ii++){ for(i=0;i<ww;i++){ putc(img2[j*ww*3+i*3+0],fpo); putc(img2[j*ww*3+i*3+1],fpo); putc(img2[j*ww*3+i*3+2],fpo); ll+=3; } } ll=ll%4; if(ll!=0){for(i=0;i<(4-ll);i++)putc(0x0,fpo);} } } printf("Done\n"); fclose(fpo); printf("%s -> %s\n",infile,outfile); }

  • 動作しない

    下のプログラムのことなのですが、このプログラムをコンパイルし、実行すると動作するのですが画像を他のものに変更して同様に実行すると動作しなくなりました。どうすればいいのでしょうか?教えてくださいお願いします。 import java.applet.*; import java.awt.*; import java.awt.image.*; public class moji extends Applet { Image img; // 元のイメージ int img_width = 0; // 元のイメージの幅 int img_height = 0; // 元のイメージの高さ int pix[]; // 元のイメージを格納する配列 int wcnt_pix[]; // 行ごとの黒画素数を格納する配列 int hcnt_pix[]; // 列ごとの黒画素数を格納する配列 int cnt = 0; // 黒画素のカウント用 int cnt_sum = 0; // 黒画素のカウント総数 int chu = 0; // 中心値 int sum1 = 0; int sum2 = 0; int x = 0; int y = 0; int xmax = 0; // 黒画素の右端 int xmin = 0; // 黒画素の左端 int ymax = 0; // 黒画素の上端 int ymin = 0; // 黒画素の下端 public void init(){ img = getImage(getDocumentBase(), "test.jpg"); // イメージのロード MediaTracker mt = new MediaTracker(this); mt.addImage(img, 0); try{ mt.waitForID(0); }catch(InterruptedException e){} // イメージのロード完了まで待機 img_width = img.getWidth(this); // 元のイメージの幅を取得 img_height = img.getHeight(this); // 元のイメージの高さを取得 cntpix(); box_top(); box_bot(); box_rig(); box_lef(); } // 黒画素数のカウント public void cntpix(){ pix = new int[img_width * img_height]; wcnt_pix = new int[img_width]; hcnt_pix = new int[img_height]; try{ PixelGrabber pg = new PixelGrabber(img, 0, 0, img_width, img_height, pix, 0, img_width); pg.grabPixels(); }catch(InterruptedException e){} // 行ごとのカウント for(int wj = 0; wj < img_height; wj++){ cnt = 0; for(int wi = 0; wi < img_width; wi++){ if((pix[wj * img_width + wi] & 255) < 128){ cnt++; } } wcnt_pix[wj] = cnt; cnt_sum = cnt_sum + cnt; } // 列ごとのカウント for(int hi = 0; hi < img_width; hi++){ cnt = 0; for(int hj = 0; hj < img_height; hj++){ if((pix[hj * img_width + hi] & 255) < 128){ cnt++; } } hcnt_pix[hi] = cnt; } chu = cnt_sum / 2; // 中心値 // 中心値より重心が何行目かを求める int i = 0; while(sum1 < chu){ sum1 = sum1 + wcnt_pix[i]; i++; } x = i - 1; // 中心値より重心が何列目かを求める int j = 0; while(sum2 < chu){ sum2 = sum2 + hcnt_pix[j]; j++; } y = j - 1; } // 黒画素の上端を求める public void box_top(){ int ti = 0; while(wcnt_pix[ti] == 0){ ymax = ti; ti++; } } // 黒画素の下端を求める public void box_bot(){ int bi = img_height - 1; while(wcnt_pix[bi] == 0){ ymin = bi; bi--; } } // 黒画素の右端を求める public void box_rig(){ int ri = 0; while(hcnt_pix[ri] == 0){ xmin = ri; ri++; } } // 黒画素の左端を求める public void box_lef(){ int li = img_width - 1; while(hcnt_pix[li] == 0){ xmax = li; li--; } } // 画像等の描画 public void paint(Graphics g){ int box_w = xmax - xmin; int box_h = ymin - ymax; int dx = x - xmin; // 重心のX座標 int saku = dx / 20 * 3; // 錯視による誤差 int dy = ymin - y + saku; // 重心のY座標 g.drawImage(img, 0, 0, this); g.drawString("このイメージの幅は"+img_width+"で高さは"+img_height+"です。", 0, 20); // 画像の描画 g.drawRect(xmin, ymax, box_w, box_h); // バウンディングボックスの描画 g.setColor(Color.red); g.fillOval(xmin-3, ymin-3, 6, 6); g.drawString("原点( 0, 0 )", xmin-20, ymin+20); // 原点の描画 g.drawString("文字の重心は、( "+dx+", "+dy+" )です。", 0, 40); // 重心の描画 g.drawLine(x-10, y-saku, x+10, y-saku); // 重心の位置の描画 g.drawLine(x, y-saku+10, x, y-saku-10); // 重心の位置の描画 } }

    • ベストアンサー
    • Java
  • 画像処理プログラム

    以下の問題でプログラムを改良したのですが合っていますか?間違ってたら教えてください 図3 は、画像中の全ての画素に対する、濃度値の頻度分布を示すヒストグラムの例である。サンプルプロググラムhistogram.c をもとに、入力画像の濃度値のヒストグラムを作成するプログラムを完成させる。 1. Histogram.c をそのまま実行すると、ダミーデータを用いた結果画像が出力される。 $ gcc □ Histogram.c -o □ Histogram ↓ $ ./Histogram ○○○.pgm □ Histogram.pgm ↓ 2. Histogram.c を次のように変更し、プログラムを完成させる。 (a)入力画像のヒストグラムを求める。 各画素を参照し、その画素値img[i][j] に対応する番号の配列histogram[0255] の値を1 増やす。 (b)頻度の最大値を求める。 濃度値i=0255 について調べ、もし頻度histogram[i] の値がそれまでの最大値max frequency より大きければ、最大値max frequency を更新する。 (c)ヒストグラム画像を作成する。 最大頻度を1 としたときの割合(histogram[i]/max frequency)を求め、それに画像の大きさH_height を掛けることで各濃度値のグラフの長さlength を求める。 length = H height * histogram[i] / max frequency #include <stdio.h> #include <stdlib.h> #define V_width 320 #define V_height 240 #define amp 1.0 #define GLEVEL 256 /* 最大階調 */ #define MAX_BRIGHTNESS 255 #define H_width GLEVEL #define H_height 256 int d[9]; int i, j, dat; float z, zz; unsigned char img [V_height][V_width]; /* input image */ unsigned char work[H_height][H_width]={0}; /* work space */ long int histogram[GLEVEL]={0}; /* ヒストグラム */ long int max_frequency=0; /* 頻度の最大値 */ float length; /* 頻度を表すグラフの長さ */ int main(int argc, char* argv[]) { FILE *fpi, *fpo; unsigned char data; char str[ 256]; int width, height; /* check arg number */ if (argc != 3) { fprintf(stderr, "Usage: %s [input] [output]\n", argv[0]); exit(1); } /* open input file */ if ((fpi = fopen(argv[1], "rb")) == NULL) { fprintf(stderr, "input file open error!\n"); exit(1); } /* open output file */ if ((fpo = fopen(argv[2], "wb")) == NULL) { fprintf(stderr, "output file open error!\n"); exit(1); } /* read PGM header */ while(1){ fgets(str, 256, fpi); if(str[0] == '#'){ fprintf( stderr, "%s", str); } else if( !strncmp( str, "P5", 2)){ fprintf( stderr, "This file is a PGM file.\n"); } else if( !strncmp( str, "255", 3)){ fprintf( stderr, "The file is opened.\n"); break; } else{ sscanf( str, "%d %d", &width, &height); fprintf( stderr, "SIZE: %3d x %3d\n", width, height); } } /* read data */ for (i=0; i<height; i++) { for (j=0; j<width; j++) { fread( &data, 1, 1, fpi); img[i][j] = data; } } /* (a) 入力画像のヒストグラムを求める */ for(i=0; i<height; i++){ for(j=0; j<width; j++){ // histogram([i][j])++; } } /* (b) 頻度の最大値を求める */ for ( i=0; i<GLEVEL; i++) { // if (histogram[i]>max_frequency) max_frequency = histogram[i]; } /* (c) ヒストグラム画像を作成する */ for (j=0; j<H_width; j++) { length = (float) H_height * j / H_width; //仮のデータ for (i=0; i<length; i++) { work[H_height-1-i][j] = MAX_BRIGHTNESS; length = H_height * histogram[i] / max_frequency } } /* write data */ fprintf(fpo,"P5\n %d %d\n 255\n", H_width, H_height); for (i= 0; i<H_height; i++) { for (j= 0; j<H_width; j++) { fwrite( &work[i][j], 1, 1, fpo); } } fclose(fpi); fclose(fpo); return 0; }

  • 表示されない

     いつもお世話になっています。早速ですが質問させていただきます。  下記のようなプログラムを作成したのですが、コンパイルは出来てもアプレットビューワーを使って実行したのですが表示されません。 教えてくださいお願いします。 import java.applet.Applet; import java.awt.*; import java.awt.image.*; public class moji extends Applet { Image img; // 元のイメージ int img_width = 0; // 元のイメージの幅 int img_height = 0; // 元のイメージの高さ int pix[]; // 元のイメージを格納する配列 int wcnt_pix[]; // 行ごとの黒画素数を格納する配列 int hcnt_pix[]; // 列ごとの黒画素数を格納する配列 int cnt = 0; // 黒画素のカウント用 int cnt_sum = 0; // 黒画素のカウント総数 int chu = 0; // 中心値 int sum1 = 0; int sum2 = 0; int x = 0; int y = 0; int xmax = 0; // 黒画素の右端 int xmin = 0; // 黒画素の左端 int ymax = 0; // 黒画素の上端 int ymin = 0; // 黒画素の下端 public void init(){ img = getImage(getDocumentBase(), "kome.jpg"); // イメージのロード MediaTracker mt = new MediaTracker(this); mt.addImage(img, 0); try{ mt.waitForID(0); }catch(InterruptedException e){} // イメージのロード完了まで待機 img_width = img.getWidth(this); // 元のイメージの幅を取得 img_height = img.getHeight(this); // 元のイメージの高さを取得 cntpix(); box_top(); box_bot(); box_rig(); box_lef(); } // 黒画素数のカウント public void cntpix(){ pix = new int[img_width * img_height]; wcnt_pix = new int[img_width]; hcnt_pix = new int[img_height]; try{ PixelGrabber pg = new PixelGrabber(img, 0, 0, img_width, img_height, pix, 0, img_width); pg.grabPixels(); }catch(InterruptedException e){} // 行ごとのカウント for(int wj = 0; wj < img_height; wj++){ cnt = 0; for(int wi = 0; wi < img_width; wi++){ if((pix[wj * img_width + wi] & 255) < 128){ cnt++; } } wcnt_pix[wj] = cnt; cnt_sum = cnt_sum + cnt; } // 列ごとのカウント for(int hi = 0; hi < img_width; hi++){ cnt = 0; for(int hj = 0; hj < img_height; hj++){ if((pix[hj * img_width + hi] & 255) < 128){ cnt++; } } hcnt_pix[hi] = cnt; } chu = cnt_sum / 2; // 中心値 // 中心値より重心が何行目かを求める int i = 0; while(sum1 < chu){ sum1 = sum1 + wcnt_pix[i]; i++; } x = i - 1; // 中心値より重心が何列目かを求める int j = 0; while(sum2 < chu){ sum2 = sum2 + hcnt_pix[j]; j++; } y = j - 1; } // 黒画素の上端を求める public void box_top(){ int ti = 0; while(wcnt_pix[ti] == 0){ ymax = ti; ti++; } } // 黒画素の下端を求める public void box_bot(){ int bi = img_height - 1; while(wcnt_pix[bi] == 0){ ymin = bi; bi--; } } // 黒画素の右端を求める public void box_rig(){ int ri = 0; while(hcnt_pix[ri] == 0){ xmin = ri; ri++; } } // 黒画素の左端を求める public void box_lef(){ int li = img_width - 1; while(hcnt_pix[li] == 0){ xmax = li; li--; } } // 画像等の描画 public void paint(Graphics g){ int box_w = xmax - xmin; int box_h = ymin - ymax; int dx = x - xmin; // 重心のX座標 int saku = dx / 20 * 3; // 錯視による誤差 int dy = ymin - y + saku; // 重心のY座標 g.drawImage(img, 0, 0, this); g.drawString("このイメージの幅は"+img_width+"で高さは"+img_height+"です。", 0, ymin+40); // 画像の描画 g.drawRect(xmin, ymax, box_w, box_h); // バウンディングボックスの描画 g.setColor(Color.red); g.fillOval(xmin-3, ymin-3, 6, 6); g.drawString("原点( 0, 0 )", xmin-20, ymin+20); // 原点の描画 g.drawString("文字の重心は、( "+dx+", "+dy+" )です。", 0, ymin+60); // 重心の描画 g.drawLine(x-10, y-saku, x+10, y-saku); // 重心の位置の描画 g.drawLine(x, y-saku+10, x, y-saku-10); // 重心の位置の描画 } }

    • ベストアンサー
    • Java
  • C言語による間引き拡大縮小

    http://csharpimage.blog60.fc2.com/blog-entry-18.html をみて、単純間引きによる拡大縮小を C言語風に書こうとしているのですが、 rescale[i+j] =layer[(int)xpos+(int)ypos];部分がよくわかりません。 24bppのRawファイル(RGB)を拡大縮小しようとしています。 rescale[i+j] =layer[(int)xpos+(int)ypos];の layer[(int)xpos+(int)ypos];部分をどうしたらいいのか悩んでいます。 layer:24bppRawを読み込むメモリ アドバイスお願い致します。m(___)m FILE *fpt_output; int width=Common_Data_Raw->width; int height=Common_Data_Raw->height; // 拡大縮小後の画像サイズ int hxSize=Common_Data_Raw->width_rescale; int hySize=Common_Data_Raw->height_rescale; // 拡大縮小用 int xSize=width; int ySize=height; double xpos, ypos; double hokanX = (double)xSize / hxSize; double hokanY = (double)ySize / hySize; unsigned char *layer,*rescale; //読み込み layer=(unsigned char*)malloc(3*width*height*sizeof(unsigned char)); fread(&layer[0],sizeof(unsigned char),3*width*height,fpt); //拡大縮小後のサイズ rescale=(unsigned char*)malloc(3*hxSize*hySize*sizeof(unsigned char)); ypos = 0.0; for (int i = 0; i < 3*hxSize*hySize; i+= 3*hxSize) { xpos = 0.0; for (int j=0;j<3*hxSize;j+=3) { // 単純補間・間引き rescale[i+j] =layer[(int)xpos+(int)ypos]; rescale[i+j+1]=layer[(int)xpos, (int)ypos]; rescale[i+j+2]=layer[(int)xpos, (int)ypos]; xpos += hokanX; } ypos += hokanY; } _wfopen_s(&fpt_output,L"output.raw",L"wb"); fwrite(&rescale[0],sizeof(unsigned char),3*width*height,fpt_output); fclose(fpt); fclose(fpt_output); free(layer); free(rescale); return 0;

  • 画像を読み込んでヒストグラムを作るプログラム

    2値化画像を読み込んで、ヒストグラムを表示させるプログラムを作りたいのですが、 以下のソースを作成したのですが実行中にエラーが発生して困っています。 よろしくお願いします。 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <conio.h> #define width 640 #define height 480 int main(int argc, char* argv[]) { unsigned char image[640*480]; unsigned char header32[1078];//ビットマップ情報 int i; int *histogram; FILE *fp1; unsigned char buffer1[640*480]; for(i=0; i<640*480; i++) { image[i]=0; buffer1[i]=0; } fp1=fopen("koshimizu1.bmp","rb"); // fread(image,1,640*480,fp1); fread(header32,1,1078,fp1); fread(buffer1,width,height,fp1); fclose(fp1); for(i=0;i<256;i++){ histogram[i]=0; } for(i=0;i<640*480;i++){ histogram[image[i]]++; } for(i=0;i<256;i++){ printf("%d %d \n",i,histogram[i]); } return 0; }