• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:線形補間法プログラム(C++))

C++で線形補間法のプログラムを組んで実行する際の注意点

このQ&Aのポイント
  • C++言語で線形補間法のプログラムを組んで実行する際に、プログラムの一部に不備がある可能性があります。
  • 線形補間法の処理に関連している部分で問題が発生しているようです。
  • プログラムの修正や、特定の値を調整する必要があるかもしれません。

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

  • ベストアンサー
  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.3

> そうすると最初にグレースケール化が必要になるのでしょうか? > どこを見てもそんなことは書いてないのですが、どこにでもある > このプログラムのimage_in[ ][ ]とはどういうことなのでしょう さ~ 私には分りません あなたのお使いの環境すら知らないのですから 当方はWindows環境で行っています 元画像がグレースケールなら グレースケール化する必要がない場合もあるでしょう グレースケールでも8階調、256階調、65536階調などその方法は沢山あります これをメモリー上に取り込むのも環境によってさまざまだと思います Unix系のXの上とか、Windows上とか DOSのG-RAMを直接いじってるとか この i,jのループの中で x,yがどのような値になるのか机上で計算してみましょう COLORREF cl[4]d ,d; cl[0] = bmp[0]->GetPixel( n + xs + 0, m + ys + 0 ); cl[1] = bmp[0]->GetPixel( n + xs + 1, m + ys + 0 ); cl[2] = bmp[0]->GetPixel( n + xs + 0, m + ys + 1 ); cl[3] = bmp[0]->GetPixel( n + xs + 1, m + ys + 1 ); といった具合に取得して d.r = (int)(1.0 - q) * (1.0 - p) * cl[0].r + p * cl[1].r + q * (1.0 - p) * cl[2].r + p * cl[3].r; d.g = (int)(1.0 - q) * (1.0 - p) * cl[0].g + p * cl[1].g + q * (1.0 - p) * cl[2].g + p * cl[3].g; d.b = (int)(1.0 - q) * (1.0 - p) * cl[0].b + p * cl[1].b + q * (1.0 - p) * cl[2].b + p * cl[3].b; pic->SetPixel( i + xs, j + ys, d ); といった具合で設定しますが SetPixel/GetPixelなどはコストの高いメソッドなのでほとんど使いません 数点の点の描画などなら使いますが ・・・ WindowsならBITMAPオブジェクトからGetBitmapBitsなどを使ってデータを取得して その上で配列操作を行います

judas15
質問者

お礼

Color color1 = bmp[0]->GetPixel(m + ys, n + xs); r1 = color1.R; g1 = color1.G; b1 = color1.B; Color color2 = bmp[0]->GetPixel(m + ys, n + xs); r2 = color2.R; g2 = color2.G; b2 = color2.B; Color color3 = bmp[0]->GetPixel(m + 1 + ys, n + xs); r3 = color3.R; g3 = color3.G; b3 = color3.B; Color color4 = bmp[0]->GetPixel(m + 1 + ys, n + 1 + xs); r4 = color4.R; g4 = color4.G; b4 = color4.B; r = (int)(((1.0 - q) * (1.0 - p) * r1) + (p * r2) + (q * (1.0 - p) * r3) + p * r4); g = (int)(((1.0 - q) * (1.0 - p) * g1) + (p * g2) + (q * (1.0 - p) * g3) + p * g4); b = (int)(((1.0 - q) * (1.0 - p) * b1) + (p * b2) + (q * (1.0 - p) * b3) + p * b4); }else{ r = 0; g = 0; b = 0; } if(r < 0){r = 0;} if(g < 0){g = 0;} if(b < 0){b = 0;} if(r > 255){r = 255;} if(g > 255){g = 255;} if(b > 255){b = 255;} Color newColor = Color::FromArgb( r, g, b ); pic->SetPixel(i + ys * 2, j + xs * 2, newColor ); } 教えてもらったことと同じような感じですが、上記のようにやってみた結果うまくいきました。ありがとうございます。 それと、(m >= -ys)&&(m < ys - 1)&&(n >= -xs)&&(n < xs - 1)の部分なのですが、-1とは何のことだったのでしょう? 線形補間された画像の右と下に線があわられてしまいました。(_|のような感じ) -1を消したら何もでなくなりましたが。 SetPixel/GetPixel以外にも画素配置の方法があるということなので、調べてみます。本当にありがとうございました。

その他の回答 (3)

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.4

(m >= -ys)&&(m < ys - 1)の ys-1は 4ピクセルのデータを収集する際の右上と右下の +1する分を考慮しないと画素のない部分を指示してしまうためです たとえば 120x120の大きさだった場合に 120,0 が左上だった場合 そのままだと 120,0 121,0 120,1 121,1 の4ピクセルを拾うことになりますが 実際には 121といったX座標がないためライブラリーがどこからデータを拾ってくるか分りません エラーになってくれればまだいいのですが ・・・

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.2

dの数式はこのままでいいと思います ループの i,jの範囲と SetPixelに与える座標のオフセットが問題なのではないかと思います for ( i = -ys * 2; i < ys * 2; i++ ) {   for ( j = -xs * 2; j < xs * 2; j++ ) {     // xypqmnの演算     if((m >= -ys)&&(m < ys -1)&&(n > -xs)&&(n < xs - 1)){       // dの演算     } esle {       d = 0     }     pic->SetPixel( i + ys * 2, j * xs * 2 ) = d;   } } といった具合でしょう

judas15
質問者

お礼

私のプログラムだと画像を2枚用意しているから2倍しているんですね。 エラーGetPixelとSetPixelの部分で、それぞれ"class に対して正しくありません。"と"関数に 2 個の引数を指定できません。"といったエラーなのですがよく考えてみたらGet(set)Pixel関数は座標指定された場所のRGBの3つデータをもらうわけですから、掛け算ができないのは当たり前です。しかし、そうすると最初にグレースケール化が必要になるのでしょうか?どこを見てもそんなことは書いてないのですが、どこにでもあるこのプログラムのimage_in[ ][ ]とはどういうことなのでしょう? //c言語線形補間法プログラム// #include "Params.h" image_in; 入力画像 image_out; 出力画像 zx; (拡大率)横 zy; (拡大率)縦 void(~){ int i,j,m,n; float x,y,p,q; int xs = X_SIZE/2; int ys = Y_SIZE/2; int d; for(i = -ys; i < ys; i++){ for(j = -xs; j < xs; j++){ y = i/zy; x = j/zx; if(y > 0){ m = (int)y; }else{ m = (int)(y-1);} if(x > 0){ n = (int)x; }else{ n = (int)(x-1);} q = y - m;  p = x - n; if(q == 1){q = 0; m = m + 1;} if(p == 1){p = 0; n = n + 1;} if((m >= -ys)&&(m < ys)&&(n >= -xs)&&(n < xs)){ d = (int)((1.0 - q) * (1.0 - p) * image_in[m + ys][n + xs] + p * image_in[m + ys][n + 1 + xs] + q * (1.0 - p) * image_in[m + 1 + ys][n + xs] + p * image_in[m + 1 + ys][n + 1 + xs]); }else{ d = 0; } if(d < 0){d = 0;} if(d > 255){d = 255;} image_out[i + ys][j + xs] = d; } } }

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.1

何に困っているのでしょう? このままだと 元画像の中心部分を2倍に伸張して『描画領域は同じ大きさ』で描画するのだと思いますが ・・・

judas15
質問者

お礼

線形補間法を使って画像のリサイズ(ここでは2倍)をするのが目的です。 最近傍法より滑らかになる画像が出力されるとのことなのでこちらを使っています。 bmp[0]には100*100pixelの画像が格納されていて、picには200*200pixelの画像が格納されています。それで拡大率であるzx(横),zy(縦)を2倍にして縦横2倍の画像(pic)を作ろうとしています。

関連するQ&A