opencv 差分 色の置換

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
kisiri
記事: 2
登録日時: 7年前

opencv 差分 色の置換

#1

投稿記事 by kisiri » 7年前

1,2,3,…と連番の画像を使い

1,2の差分を取る
その差分を1で一番使われていない色に変える
1と合成する(2改となる)
2改と3の差分を取る
その差分を・・・


といった処理を実装している(したい)のですが
その差分がすべて黒色になって配置されてしまいます
どこが間違っているのか教えていただきたいです

rgbの判定自体は183行目で確認して問題ないはずなのですがcRGB = rgb(r3, g3, b3);のとこではおかしくなってるようです・・・


色の判定は0,63,126,192,255のrgbの組み合わせで差分もその中で置換されるようにしています

コード:

using namespace cv;
using namespace std;

int rr(int cc);
int gg(int cc);
int bb(int cc);
int rgb(int r, int g, int b);
int min(int hist[]);

int main(int argc, char* argv[]){
	IplImage *Img_orig;
	IplImage *Img_1st;
	IplImage *Img_2nd;
	IplImage *Img_gosei;
	IplImage *Img_gnow;
	//IplImage *Img_gnow2;
	int W, H; //widthとheight
	int cRGB = 0;
	int ii;
	int Min;
	char filename1[256];
	char filename2[256];
	int hist_orig[125];
	int hist_gosei[125];
	//int hist_2nd[125];
	FILE *outputfile;         // 出力ストリーム
	fopen_s(&outputfile, "d.txt", "w");  // ファイルを書き込み用にオープン(開く)


	Img_orig = cvLoadImage("0000.png", 1);
	Img_gosei = cvLoadImage("0000.png", 1);
	W = Img_orig->width;//幅
	H = Img_orig->height;//高さ

	Img_gnow = cvCreateImage(cvSize(W, H), IPL_DEPTH_8U, 3); //カラー
	//Img_gnow2 = cvCreateImage(cvSize(W, H), IPL_DEPTH_8U, 3); //カラー

	//Img_gnow2 = cvCloneImage(Img_gnow);



	//////////////////////////////////////////////////////////////////////////////////////////////////枚数
	for (ii = 0; ii <= 1; ii++){

		//ヒストグラム格納配列初期化
		for (int c = 0; c < 125; c++){
			hist_orig[c] = 0;
			hist_gosei[c] = 0;
		}

		//差分初期化
		for (int y = 0; y < H; y++) {
			for (int x = 0; x < W; x++) {
				Img_gnow->imageData[Img_gnow->widthStep * y + x * 3] = 32;
				Img_gnow->imageData[Img_gnow->widthStep * y + x * 3 + 1] = 32;
				Img_gnow->imageData[Img_gnow->widthStep * y + x * 3 + 2] = 32;
			}
		}

		//順番に画像の読み込み
		sprintf_s(filename1, 30, "%04d.png", ii);
		sprintf_s(filename2, 30, "%04d.png", ii + 1);
		//printf("%s  ,  %s\n", filename1, filename2);
		Img_1st = cvLoadImage(filename1, 1);
		Img_2nd = cvLoadImage(filename2, 1);

		//画素の確認
		for (int y = 0; y < H; y++) {
			for (int x = 0; x < W; x++) {
				int b1 = Img_1st->imageData[Img_1st->widthStep * y + x * 3];
				int g1 = Img_1st->imageData[Img_1st->widthStep * y + x * 3 + 1];
				int r1 = Img_1st->imageData[Img_1st->widthStep * y + x * 3 + 2];

				int b2 = Img_2nd->imageData[Img_2nd->widthStep * y + x * 3];
				int g2 = Img_2nd->imageData[Img_2nd->widthStep * y + x * 3 + 1];
				int r2 = Img_2nd->imageData[Img_2nd->widthStep * y + x * 3 + 2];

				int b3 = Img_gosei->imageData[Img_gosei->widthStep * y + x * 3];
				int g3 = Img_gosei->imageData[Img_gosei->widthStep * y + x * 3 + 1];
				int r3 = Img_gosei->imageData[Img_gosei->widthStep * y + x * 3 + 2];

				//goseiのヒストグラム取得
				cRGB = rgb(r3, g3, b3);

				if (ii == 0) fprintf(outputfile, "yaaaaaaaaaaaaaaaaaaaaaaaa"), fprintf(outputfile, "\n %( %5d)", cRGB);

				//printf("\n()()()()()()%d :", cRGB);
				fprintf(outputfile, "\n %( %5d)", cRGB);
				hist_gosei[cRGB]++;
				if (ii == 0)	hist_orig[cRGB]++;

				//差分を保存
				if (b1 != b2 || g1 != g2 || r1 != r2) {
					Img_gnow->imageData[Img_gnow->widthStep * y + x * 3] = b2;
					Img_gnow->imageData[Img_gnow->widthStep * y + x * 3 + 1] = g2;
					Img_gnow->imageData[Img_gnow->widthStep * y + x * 3 + 2] = r2;
				}
			}
		}



		//使用頻度の低い色を検索
		Min = min(hist_gosei);
		int r = rr(Min);
		int g = gg(Min);
		int b = bb(Min);
		//printf("(%d , %d , %d)\n",r,g,b);

		//r = 100, g = 100, b = 100;


		//色を置換
		for (int y = 0; y < H; y++) {
			for (int x = 0; x < W; x++) {
				if (Img_gnow->imageData[Img_gnow->widthStep * y + x * 3] != 32 && Img_gnow->imageData[Img_gnow->widthStep * y + x * 3 + 1] != 32 && Img_gnow->imageData[Img_gnow->widthStep * y + x * 3 + 2] != 32){
					Img_gosei->imageData[Img_gosei->widthStep * y + x * 3] = b;
					Img_gosei->imageData[Img_gosei->widthStep * y + x * 3 + 1] = g;
					Img_gosei->imageData[Img_gosei->widthStep * y + x * 3 + 2] = r;
				}
			}
		}


		//printf("\n()()()()()()%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%()()()()()()()()()()()()()()()()()()()()()()() :");
	}
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	//for (int a = 0; a < 125; a++){
	//	fprintf(outputfile, "\n %d :( %5d)", a, hist_orig[cRGB]);
	//}

	//for (int c = 0; c < 255; c+=63){
	//	for (int b = 0; b < 255; b+=63){
	//		for (int a = 0; a < 255; a+=63){
	//			cRGB = rgb(c, b, a);
	//			printf("     %d     \n",cRGB);
	//		}
	//	}
	//}


	//画像の表示
	cvShowImage("元画像", Img_orig);
	cvShowImage("1st", Img_1st);
	cvShowImage("2nd", Img_2nd);
	cvShowImage("gosei", Img_gosei);
	cvShowImage("gnow", Img_gnow);

	//画像の保存
	//cvSaveImage("No_5a.png", Img_gray);
	cvSaveImage("No_5c.png", Img_gosei);

	//キー入力待機
	cvWaitKey(0);

	//ウィンドウの破棄
	cvDestroyAllWindows();

	//画像リソースの解放
	cvReleaseImage(&Img_1st);
	cvReleaseImage(&Img_2nd);
	cvReleaseImage(&Img_orig);
	cvReleaseImage(&Img_gosei);
	fclose(outputfile);          // ファイルをクローズ(閉じる)
	return 0;
}



int rr(int cc){
	int rr;
	if (cc >= 0 && cc <= 24){
		rr = 0;
	}
	else if (cc <= 25 && cc <= 49){
		rr = 64;
	}
	else if (cc >= 50 && cc <= 74){
		rr = 128;
	}
	else if (cc >= 75 && cc <= 99){
		rr = 192;
	}
	else if (cc >= 100 && cc <= 124){
		rr = 255;
	}
	return rr;
}

int gg(int cc){
	int gg;
	if ((cc >= 0 && cc <= 4) || (cc >= 25 && cc <= 29) || (cc >= 50 && cc <= 54) || (cc >= 75 && cc <= 79) || (cc >= 100 && cc <= 104)){
		gg = 0;
	}
	else if ((cc >= 5 && cc <= 9) || (cc >= 30 && cc <= 34) || (cc >= 55 && cc <= 59) || (cc >= 80 && cc <= 84) || (cc >= 105 && cc <= 109)){
		gg = 64;
	}
	else if ((cc >= 10 && cc <= 14) || (cc >= 35 && cc <= 39) || (cc >= 60 && cc <= 64) || (cc >= 85 && cc <= 89) || (cc >= 110 && cc <= 114)){
		gg = 128;
	}
	else  if ((cc >= 15 && cc <= 19) || (cc >= 40 && cc <= 44) || (cc >= 65 && cc <= 69) || (cc >= 90 && cc <= 94) || (cc >= 115 && cc <= 119)){
		gg = 192;
	}
	else if ((cc >= 20 && cc <= 24) || (cc >= 45 && cc <= 49) || (cc >= 70 && cc <= 74) || (cc >= 95 && cc <= 99) || (cc >= 120 && cc <= 124)){
		gg = 255;
	}
	return gg;
}

int bb(int cc){
	int bb;
	if (cc % 5 == 0){
		bb = 0;
	}
	else if (cc % 5 == 1){
		bb = 64;
	}
	else if (cc % 5 == 2){
		bb = 128;
	}
	else if (cc % 5 == 3){
		bb = 192;
	}
	else if (cc % 5 == 4){
		bb = 255;
	}
	return bb;
}

int rgb(int r, int g, int b){
	int cc;

	if (r < 32) {
		if (g < 32) {
			if (b < 32) {
				cc = 0;
			}
			else if (b >= 32 && b < 96) {
				cc = 1;
			}
			else if (b >= 96 && b < 160) {
				cc = 2;
			}
			else if (b >= 160 && b < 224) {
				cc = 3;
			}
			else if (b >= 225) {
				cc = 4;
			}
		}
		else if (g >= 32 && g < 96) {
			if (b < 32) {
				cc = 5;
			}
			else if (b >= 32 && b < 96) {
				cc = 6;
			}
			else if (b >= 96 && b < 160) {
				cc = 7;
			}
			else if (b >= 160 && b < 224) {
				cc = 8;
			}
			else if (b >= 225) {
				cc = 9;
			}
		}
		else if (g >= 96 && g < 160) {
			if (b < 32) {
				cc = 10;
			}
			else if (b >= 32 && b < 96) {
				cc = 11;
			}
			else if (b >= 96 && b < 160) {
				cc = 12;
			}
			else if (b >= 160 && b < 224) {
				cc = 13;
			}
			else if (b >= 225) {
				cc = 14;
			}
		}
		else if (g >= 160 && g < 224) {
			if (b < 32) {
				cc = 15;
			}
			else if (b >= 32 && b < 96) {
				cc = 16;
			}
			else if (b >= 96 && b < 160) {
				cc = 17;
			}
			else if (b >= 160 && b < 224) {
				cc = 18;
			}
			else if (b >= 225) {
				cc = 19;
			}
		}
		else if (g >= 225) {
			if (b < 32) {
				cc = 20;
			}
			else if (b >= 32 && b < 96) {
				cc = 21;
			}
			else if (b >= 96 && b < 160) {
				cc = 22;
			}
			else if (b >= 160 && b < 224) {
				cc = 23;
			}
			else if (b >= 225) {
				cc = 24;
			}
		}
	}
	else if (r >= 32 && r < 96) {
		if (g < 32) {
			if (b < 32) {
				cc = 25;
			}
			else if (b >= 32 && b < 96) {
				cc = 26;
			}
			else if (b >= 64 && b < 160) {
				cc = 27;
			}
			else if (b >= 160 && b < 224) {
				cc = 28;
			}
			else if (b >= 225) {
				cc = 29;
			}
		}
		else if (g >= 32 && g < 96) {
			if (b < 32) {
				cc = 30;
			}
			else if (b >= 32 && b < 96) {
				cc = 31;
			}
			else if (b >= 64 && b < 160) {
				cc = 32;
			}
			else if (b >= 160 && b < 224) {
				cc = 33;
			}
			else if (b >= 225) {
				cc = 34;
			}
		}
		else if (g >= 96 && g < 160) {
			if (b < 32) {
				cc = 35;
			}
			else if (b >= 32 && b < 96) {
				cc = 36;
			}
			else if (b >= 64 && b < 160) {
				cc = 37;
			}
			else if (b >= 160 && b < 224) {
				cc = 38;
			}
			else if (b >= 225) {
				cc = 39;
			}
		}
		else if (g < 224) {
			if (b < 32) {
				cc = 40;
			}
			else if (b >= 32 && b < 96) {
				cc = 41;
			}
			else if (b >= 64 && b < 160) {
				cc = 42;
			}
			else if (b >= 160 && b < 224) {
				cc = 43;
			}
			else if (b >= 225) {
				cc = 44;
			}
		}
		else if (g >= 225) {
			if (b < 32) {
				cc = 45;
			}
			else if (b >= 32 && b < 96) {
				cc = 46;
			}
			else if (b >= 64 && b < 160) {
				cc = 47;
			}
			else if (b >= 160 && b < 224) {
				cc = 48;
			}
			else if (b >= 225) {
				cc = 49;
			}
		}
	}
	else if (r >= 96 && r < 160) {
		if (g < 32) {
			if (b < 32) {
				cc = 50;
			}
			else if (b >= 32 && b < 96) {
				cc = 51;
			}
			else if (b >= 64 && b < 160) {
				cc = 52;
			}
			else if (b >= 160 && b < 224) {
				cc = 53;
			}
			else if (b >= 225) {
				cc = 54;
			}
		}
		else if (g >= 32 && g < 96) {
			if (b < 32) {
				cc = 55;
			}
			else if (b >= 32 && b < 96) {
				cc = 56;
			}
			else if (b >= 64 && b < 160) {
				cc = 57;
			}
			else if (b >= 160 && b < 224) {
				cc = 58;
			}
			else if (b >= 225) {
				cc = 59;
			}
		}
		else if (g >= 96 && g < 160) {
			if (b < 32) {
				cc = 60;
			}
			else if (b >= 32 && b < 96) {
				cc = 61;
			}
			else if (b >= 64 && b < 160) {
				cc = 62;
			}
			else if (b >= 160 && b < 224) {
				cc = 63;
			}
			else if (b >= 225) {
				cc = 64;
			}
		}
		else if (g < 224) {
			if (b < 32) {
				cc = 65;
			}
			else if (b >= 32 && b < 96) {
				cc = 66;
			}
			else if (b >= 64 && b < 160) {
				cc = 67;
			}
			else if (b >= 160 && b < 224) {
				cc = 68;
			}
			else if (b >= 225) {
				cc = 69;
			}
		}
		else if (g >= 225) {
			if (b < 32) {
				cc = 70;
			}
			else if (b >= 32 && b < 96) {
				cc = 71;
			}
			else if (b >= 64 && b < 160) {
				cc = 72;
			}
			else if (b >= 160 && b < 224) {
				cc = 73;
			}
			else if (b >= 225) {
				cc = 74;
			}
		}
	}
	else if (r >= 160 && r < 224) {
		if (g < 32) {
			if (b < 32) {
				cc = 75;
			}
			else if (b >= 32 && b < 96) {
				cc = 76;
			}
			else if (b >= 64 && b < 160) {
				cc = 77;
			}
			else if (b >= 160 && b < 224) {
				cc = 78;
			}
			else if (b >= 225) {
				cc = 79;
			}
		}
		else if (g >= 32 && g < 96) {
			if (b < 32) {
				cc = 80;
			}
			else if (b >= 32 && b < 96) {
				cc = 81;
			}
			else if (b >= 64 && b < 160) {
				cc = 82;
			}
			else if (b >= 160 && b < 224) {
				cc = 83;
			}
			else if (b >= 225) {
				cc = 84;
			}
		}
		else if (g >= 96 && g < 160) {
			if (b < 32) {
				cc = 85;
			}
			else if (b >= 32 && b < 96) {
				cc = 86;
			}
			else if (b >= 64 && b < 160) {
				cc = 87;
			}
			else if (b >= 160 && b < 224) {
				cc = 88;
			}
			else if (b >= 225) {
				cc = 89;
			}
		}
		else if (g >= 160 && g < 224) {
			if (b < 32) {
				cc = 90;
			}
			else if (b >= 32 && b < 96) {
				cc = 91;
			}
			else if (b >= 64 && b < 160) {
				cc = 92;
			}
			else if (b >= 160 && b < 224) {
				cc = 93;
			}
			else if (b >= 225) {
				cc = 94;
			}
		}
		else if (g >= 225) {
			if (b < 32) {
				cc = 95;
			}
			else if (b >= 32 && b < 96) {
				cc = 96;
			}
			else if (b >= 64 && b < 160) {
				cc = 97;
			}
			else if (b >= 160 && b < 224) {
				cc = 98;
			}
			else if (b >= 225) {
				cc = 99;
			}
		}
	}
	else if (r >= 225) {
		if (g < 32) {
			if (b < 32) {
				cc = 100;
			}
			else if (b >= 32 && b < 96) {
				cc = 101;
			}
			else if (b >= 64 && b < 160) {
				cc = 102;
			}
			else if (b >= 160 && b < 224) {
				cc = 103;
			}
			else if (b >= 225) {
				cc = 104;
			}
		}
		else if (g >= 32 && g < 96) {
			if (b < 32) {
				cc = 105;
			}
			else if (b >= 32 && b < 96) {
				cc = 106;
			}
			else if (b >= 64 && b < 160) {
				cc = 107;
			}
			else if (b >= 160 && b < 224) {
				cc = 108;
			}
			else if (b >= 225) {
				cc = 109;
			}
		}
		else if (g >= 96 && g < 160) {
			if (b < 32) {
				cc = 110;
			}
			else if (b >= 32 && b < 96) {
				cc = 111;
			}
			else if (b >= 64 && b < 160) {
				cc = 112;
			}
			else if (b >= 160 && b < 224) {
				cc = 113;
			}
			else if (b >= 225) {
				cc = 114;
			}
		}
		else if (g >= 160 && g < 224) {
			if (b < 32) {
				cc = 115;
			}
			else if (b >= 32 && b < 96) {
				cc = 116;
			}
			else if (b >= 64 && b < 160) {
				cc = 117;
			}
			else if (b >= 160 && b < 224) {
				cc = 118;
			}
			else if (b >= 225) {
				cc = 119;
			}
		}
		else if (g >= 225) {
			if (b < 32) {
				cc = 120;
			}
			else if (b >= 32 && b < 96) {
				cc = 121;
			}
			else if (b >= 64 && b < 160) {
				cc = 122;
			}
			else if (b >= 160 && b < 224) {
				cc = 123;
			}
			else if (b >= 225) {
				cc = 124;
			}
		}
	}
	//printf("cc=%d\n",cc);
	return cc;
}

int min(int hist[]){

	int min;
	int i;
	min = hist[0];
	for (i = 0; i < 125; i++){
		//printf("\n%10d :", hist[i]);
		if (hist[i] < min){
			min = hist[i];
		}
	}
	return min;
}

添付ファイル
gazou.zip
(74.66 KiB) ダウンロード数: 116 回

kisiri
記事: 2
登録日時: 7年前

Re: opencv 差分 色の置換

#2

投稿記事 by kisiri » 7年前

70~80行目で(unsigned char)の記述が足りず判定がおかしくなっていました

そして今度はhist配列の格納ができてないみたいなので引き続きやっていきます・・・

かずま

Re: opencv 差分 色の置換

#3

投稿記事 by かずま » 7年前

解決には至らないと思いますが、
気づいたところをお知らせします。

176行目: cc <= 25 は、cc >= 25 でしょう。
188行目: cc >= 125 の場合、rr が不定です。

規則的なものは、簡単に書けます。

コード:

int rr(int cc)
{
    int r = cc / 25 * 64;
    return r > 255 ? 255 : r;
}

int gg(int cc)
{
    int g = cc / 5 % 5 * 64;
    return g > 255 ? 255 : g;
}
 
int bb(int cc)
{
    int b = cc % 5 * 64;
    return b > 255 ? 255 : b;
}
 
int rgb(int r, int g, int b)
{
    return (r + 32) / 64 * 25 + (g + 32) / 64 * 5 + (b + 32) / 64;
}

返信

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