画像の上下反転について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ubuntu

画像の上下反転について

#1

投稿記事 by ubuntu » 16年前

はじめましてubuntuと申します。
今回画像処理プログラミングを学習していて、ひっかかった部分がありまして、このサイトで何か良い
アドバイスをもらえたらと書き込みさせてもらいました。
//各画素の濃度値を順番にコピーする
	for(j=0;j<<img->height;j++){    // j:画像のy座標、img:元の画像、:height:画像の高さ
		for(i=0;i<<img->width;i++){ // i:画像のx座標、width:画像の幅
			p=j*img->width*3+i*3; // 各画素の濃度値と配列番号の対応公式
                          // outimg:コピー後の画像
			outimg->data[p]=img->data[p];   // 赤の画素値
			outimg->data[p+1]=img->data[p+1]; // 緑の画素値
			outimg->data[p+2]=img->data[p+2]; // 赤の画素値
		}
	}
上のソースでは、1つの画像をそのまま完全コピーするプログラムソースの一部なのですが、この部分だけを
変更して画像を上下反転させたいのですが、何か良い方法ありませんか?
何かアドバイスよろしくお願いします。

SooA

Re:画像の上下反転について

#2

投稿記事 by SooA » 16年前

先ず貼ってあるソースの内容を理解してみましょう。
プログラムは 0,0 の位置から横幅(width)をコピーする処理を、
縦幅(height)の回数繰り返しているのは解りますか?
現在の処理
img(読取)  outimg(書込)
↓ここから ↓ここから
■■■■■ ■■■■■
■■□□□→■■□□□
□□□□□ □□□□□

上下に反転させたいのであれば
データの上下だけ逆に書き込んでいきます。

img(読取)  outimg(書込)
↓ここから
■■■■■ □□□□□
■■□□□→■■□□□
□□□□□ ■■■■■
            ↑ここから

ubuntu

Re:画像の上下反転について

#3

投稿記事 by ubuntu » 16年前

SooAさん回答ありがとうございました。
SooAさんの考え方でやってみたのですが、コードがおかしいのか、うまくできません。
for(j=0;j<<img->height;j++){
		for(i=0;i<<img->width;i++){
			p=j*img->width*3+i*3;
			outimg->data[p]=img->data[p];
			outimg->data[p+1]=img->data[p+1];
			outimg->data[p+2]=img->data[p+2];
		}
	}
	for(j=img->height-1;j>=0;j--){
		for(i=0;i<<img->width;i++){
			q=j*img->width*3+i*3;
			outimg->data[q]=img->data[p];
			outimg->data[q+1]=img->data[p+1];
			outimg->data[q+2]=img->data[p+2];
		}
	}
こんな感じで逆からimgの濃度値をoutimgの配列にコピーしたのですがうまくいきません。
このコードではダメなのでしょうか?回答お願いします。

SooA

Re:画像の上下反転について

#4

投稿記事 by SooA » 16年前

何故か処理が増えてますが、
読み込むデータと書き込むデータは

outimg->data[p] = img->data[p];
↑書き込む側   ↑読み込む側
の部分ですので for文を逆にしても
pの値が同じなのでコピーする位置は変わりません。
//各画素の濃度値を順番にコピーする
	int x , y, r, w ;

	// 画像の y座標、img:元の画像、:height:画像の高さ
	for( y=0; y<height; y++ )
	{
		// 画像の x座標、width:画像の幅
		for( x=0; x<width; x++ )
		{
			// 読み取り位置
			r = y*img->width*3 + x*3 ;

			// 書き込み位置
			w = ( (height-1)-y )*img->width*3 + x*3 ;

			// コピー後の画像
			outimg->data[w] = img->data[[/url] ;
			outimg->data[w+1] = img->data[r+1] ;
			outimg->data[w+2] = img->data[r+2] ;
		}
	}

SooA

Re:画像の上下反転について

#5

投稿記事 by SooA » 16年前

> このコードではダメなのでしょうか?回答お願いします。
よく見ると変数qを使っていますが、
下部ループでの読み取り位置pが全く変化していないので
画像AをBに複製した後に、
画像Aの終端のデータでBを埋め尽くす。
といった感じの処理になっていると思います。

ubuntu

Re:画像の上下反転について

#6

投稿記事 by ubuntu » 16年前

SooAさん回答ありがとうございました。
SooAさんのとおり変更したら上手くいきました。
とても参考になりました。
質問なのですが、
for(j=0;j<<img->height;j++){    //  #1
		for(i=0;i<<img->width;i++){
			p=j*img->width*3+i*3;
			outimg->data[p]=img->data[p];
			outimg->data[p+1]=img->data[p+1];
			outimg->data[p+2]=img->data[p+2];
		}
	}
	for(j=img->height-1;j>=0;j--){   //   #2
		for(i=0;i<<img->width;i++){
			q=j*img->width*3+i*3;
			outimg->data[q]=img->data[p];
			outimg->data[q+1]=img->data[p+1];
			outimg->data[q+2]=img->data[p+2];
		}
	}
先ほどのコードで、なぜ#2のfor部分でコピー元のデータ(img->data[p])を書き込み用データ配列(outimg->data[q])に逆から入れる処理をしていてうまくできないのかがよく分かりませんでした。
配列の番号[p],[q]では値が異なるため、配列自身の値も変わってくるのではないのでしょうか?
初心者的質問で恐縮なのですが、回答お願いします。

ubuntu

Re:画像の上下反転について

#7

投稿記事 by ubuntu » 16年前

SooAさんすみません。
よくよく考えてみたら、とても馬鹿な質問をしていました。
今完璧理解できました。
お手数かけて申し訳ありません。

ビギナー

ソート

#8

投稿記事 by ビギナー » 16年前

こんばんは、初心者です。
ソートについてです。
書いてある説明はわかるのですが、いざプログラミングしてみると
正直、どのような処理が行われているのかわかりません。
下記は、手伝っていただき、出来たものです。

よろしければ、どのような処理が行われているのかコメントしていただけませんか?

//~が行われている

など簡単でかまいません。
また、お時間がありましたら、詳しい解説をお願い致します。
#include <stdio.h>

#include <string.h>

#define N 10

void main(void)
{
	static struct girl {
		char *name;
		int year;
	} *t,*p[N],a[/url]={"Ann",18,"Rolla",19,"Nancy",16,"Eluza",17,"Juliet",18,
					"Machilda",20,"Emy",15,"Candy",16,"Ema",17,"Mari",18};
	char *min;
	int s, i, j;

	for(i=0;i<N;i++)
		p=&a;

	for(i=0;i<N-1;i++){
		min=p->name;
		s=i;
		for(j=i+1;j<N;j++){
			if (strcmp(p[j]->name,min)<0){
				min=p[j]->name;
				s=j;
			}
		}
		t=p; p=p; p=t;
	}

	for(i=0;i<N;i++)
		printf("%10s%4d\n",p->name,p->year);
}

kazuoni

Re:ソート

#9

投稿記事 by kazuoni » 16年前

#include <stdio.h>

#include <string.h>

#define N 10

void main(void)
{
	// 構造体の定義&変数宣言
	static struct girl {
		char *name;
		int year;
	} *t,*p[N],a[/url]={"Ann",18,"Rolla",19,"Nancy",16,"Eluza",17,"Juliet",18,

					"Machilda",20,"Emy",15,"Candy",16,"Ema",17,"Mari",18};

	char *min;

	int s, i, j;

	// 配列aの各配列の要素のアドレスをpに代入する
	// 値コピーではないので、pの要素を書き換える=aの要素を書き換える
	for(i=0;i<N;i++)

		p=&a;

	// pの要素を昇順もしくは降順にソートする。
	// strcmpの戻り値の「0より大きいか」「0より小さいか」は文字コードに依存するので、昇順か降順かは環境依存
	// 自分は降順で表示される環境が何かまでは知りませんが・・・
	for(i=0;i<N-1;i++){
		min=p->name; // ソート対象のnameをコピー
		s=i; // ソート対象のyearをコピー

		for(j=i+1;j<N;j++){
			// p[j]name-num(p->name)<0かどうか比較
			// 真ならば並びかえるために必要な情報を更新
			if (strcmp(p[j]->name,min)<0){ 
				min=p[j]->name;
				s=j;
			}
		}

		// 交換する。
		// 交換しない時は、s=iなので、自分自身の内容がコピーされる。
		t=p; p=p; p=t;
	}

	for(i=0;i<N;i++) // 出力
		printf("%10s%4d\n",p->name,p->year);
}


ソートの詳しい解説は、バブルソートで検索してみてください。

ビギナー

Re:ソート

#10

投稿記事 by ビギナー » 16年前

詳しくありがとうございます。

ですが、まだ初心者の自分には難しいです^^;
ポインタは難しいと聞いてますし、理解できない自分が情けないです。

もっと詳しい解説は可能でしょうか?

お手数ですがよろしくお願いします。

kazuoni

Re:ソート

#11

投稿記事 by kazuoni » 16年前

理解できないところを列挙してみてください。
できる限り詳しく解説します。
その際、一度自分で調べることも重要かと。
聞けばなんとなくわかる→プログラムを組む時にやっぱり同じところで躓く
ってことがありがちです(少なくとも自分はそうでした。)

自分で出来る限り、参考書またはネットのページで調べて、
それでも理解できなかったら質問っという形がベストかと思います。

Hermit

Re:ソート

#12

投稿記事 by Hermit » 16年前

//http://ja.wikipedia.org/wiki/%E9%81%B8% ... C%E3%83%88
//選択ソート 参照
#include <stdio.h>
#include <string.h>
#define N 10
int main(void) {
   static struct girl {
      char *name;
      int year;
   } data[/url] = {
   "Ann", 18, "Rolla", 19, "Nancy", 16, "Eluza", 17, "Juliet", 18,
          "Machilda", 20, "Emy", 15, "Candy", 16, "Ema", 17, "Mari", 18};
   int i, j;

   for (i = 0; i < N - 1; i++) {
      int min = i;
      struct girl swapTmp;
      for (j = i + 1; j < N; j++)
         if (strcmp(data[j].name, data[min].name) < 0)
            min = j;
      swapTmp = data;
      data = data[min];
      data[min] = swapTmp;
   }
   for (i = 0; i < N; i++)
      printf("%10s%4d\n", data.name, data.year);
}
ソートにあまり関係なさそうなところを削ってみました。

閉鎖

“C言語何でも質問掲示板” へ戻る