C++言語で線形補間法のプログラムを組んで実行しているのですが、どしてもうまくいきません。ただ2倍の画像を作っているだけなのですが・・・。
以下プログラムを載せます、おおよその場所はわかるのですがどうすれば通るのかわかりません。どう直したらよいのか分かる方がいましたらご教授お願いします。
※bmp[0]:現画像 pic:bmp[0]の縦横2倍の画像
// 線形補間法 //
int zx = 2;
int zy = 2;
int i,j,m,n;
float x,y,p,q;
int xs = bmp[0]->Width/2;
int ys = bmp[0]->Height/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) * (bmp[0]->GetPixel( m + ys, n + xs)) //おそらくこの辺に問題があるかと思われます。
+ p * (bmp[0]->GetPixel( m +ys, n + xs))
+ q * (1.0 - p) * (bmp[0]->GetPixel(m + 1 + ys, n + xs))
+ p * (bmp[0]->GetPixel(m + 1 + ys, n + 1 + xs)));
}else{
d = 0;
}
if(d < 0){d = 0;}
if(d > 255){d = 255;}
pic->SetPixel(i + ys, j + xs) = d;
}
}
pictureBox2->Image = pic;
}
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座標がないためライブラリーがどこからデータを拾ってくるか分りません
エラーになってくれればまだいいのですが ・・・
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などを使ってデータを取得して
その上で配列操作を行います
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以外にも画素配置の方法があるということなので、調べてみます。本当にありがとうございました。
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;
}
}
といった具合でしょう
私のプログラムだと画像を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;
}
}
}
No.1
- 回答日時:
何に困っているのでしょう?
このままだと 元画像の中心部分を2倍に伸張して『描画領域は同じ大きさ』で描画するのだと思いますが ・・・
線形補間法を使って画像のリサイズ(ここでは2倍)をするのが目的です。
最近傍法より滑らかになる画像が出力されるとのことなのでこちらを使っています。
bmp[0]には100*100pixelの画像が格納されていて、picには200*200pixelの画像が格納されています。それで拡大率であるzx(横),zy(縦)を2倍にして縦横2倍の画像(pic)を作ろうとしています。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# プログラムの時、フローチャートはどうなりますか?図でお願いします。 int main(void) { 1 2022/10/01 22:45
- C言語・C++・C# プログラミング c言語 4 2023/03/07 01:05
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# C言語 3 2022/11/09 13:27
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- Ruby 【JAVA】数字をひし形に出力するプログラムについて 2 2022/07/11 23:32
- C言語・C++・C# C 言語の Gauss Jordan 法について 2 2022/12/28 11:16
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# 並列プログラミングのπ計算について 1 2022/07/16 22:30
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語で%を使わない余りの出し方
-
分数の足し算をさせるプログラ...
-
nCrの計算
-
C言語
-
カードシャッフルのブログラム...
-
CppUnitはCプログラムにも使え...
-
intとlongは同じ?
-
ハフマン符号化の問題を解くプ...
-
C++で表を作成したいのです ...
-
プログラミング
-
VC++でコマンドラインから引数...
-
C言語 サイコロ 2つの値を返せない
-
2÷3などの余りについて
-
比較回数と交換回数表示について
-
信頼区間の1.96や1.65ってどこ...
-
nCmの関数
-
複数桁10進数の*桁目だけを抽出...
-
Notepad++の関数リスト表示の変...
-
C言語のfor文です。 繰り返しの...
-
break文でループを一気に抜ける...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
2の補数を計算するプログラム
-
intとlongは同じ?
-
再起呼び出しの回数をカウント...
-
C言語で%を使わない余りの出し方
-
迷路を脱出する経路探索プログ...
-
画像の拡大・縮小
-
分数の足し算をさせるプログラ...
-
C言語で簡単なパックマンゲーム...
-
C++で表を作成したいのです ...
-
条件が多い場合
-
複数の共有メモリの作成
-
ヒストグラム均等化処理プログラム
-
3のつく数と3の倍数を表示 C言語
-
argvのNULLチェック
-
乱数で交互に偶数、奇数が、、、。
-
プログラミングに関して
-
OpenCVによる4値化について
-
再帰処理をループ処理に変換
-
16bitで乱数を生成する方法
-
C++ Debug Errorについて教えて
おすすめ情報