初心者なんで言葉が適切でないかも知れませんがお許しください。
”0”、”1”(白黒の対応)でできている何行何列かできている画像を読みこんで、自分が指定したある画像の一部の場所を出力するプログラムを作成したいのですがどうしたらよいのかさっぱりわかりません。
1ビットが白か黒か判断することはできたのですが、だれか教えていただけないでしょうか?御願いします。

このQ&Aに関連する最新のQ&A

A 回答 (3件)

もしかして、画像そのものをロードする方法とか、セーブする方法のことが「どうしたらよいのかさっぱり」の部分なんでしょうか?


だとしたら、一番お手軽なのはBMPファイルでしょうかね。ベクターにも解説書があります。

参考URL:http://www.vector.co.jp/soft/data/art/se027618.h …
    • good
    • 0

>・・・言葉が適切でないかも知れませんが・・



確かに・・状況が把握しきれないんで、かなり推定はいってますけど・・・

質問の感じでは、テンプレートマッチングでOKじゃないかな。

「自分が指定したある画像」をテンプレートということにしてーー--テンプレートの原点を読み込んだ画像のいろんな位置に移動して重ねあわせていくとぴったりあうかどうかわかります。

ぴったりあうかどうか、ってのは・・・
ある位置でテンプレートの画素の値(1/0)と読み込んだ画像の画素の値(1/0)のXORを合計します。この値が小さいほどより合致していることになるわけ。

1画素ずつずらして、この値が0(か最小)になるところをさがしましょ。(forループが何重かになるはずじゃ)

これだけでも絵のサイズがでかいと相当の計算量だけど、「探す絵が傾きます」なんてことになるともう大変。
少しずつ傾いたテンプレートで繰り返し~。

さらに「1/0じゃなくて、グレイスケールなんよ」だったら、ぴったり0じゃない(ことが多い)からどえらいことになってしまう。

まじめにやってたら、きりがない。冗談じゃないってことで、モザイク処理してから大まかに当たりをつけて、あやしいとこを更に細かく計算するとかーーーまぁ、いろんな工夫があるよ。

とにかく、画像処理は面白いよ。
全体的な戦略を考えながら、ループの中のコード(Cばかりでなく機械語まで)最適化を考える。最後はハードまで....ガッチリハマっても後悔しないよ。
    • good
    • 0
この回答へのお礼

ありがとうございました。
先が見えてきました。いろいろなものを調べて
完成させたいと思います。

お礼日時:2001/06/10 01:12

判断したものを同じようにテーブル(2次元配列など)に置き換えていけば


良いんじゃないですか?

そして、指定されたところを出力する。
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q白黒ビットマップの表示

はじめて質問させていただきます。勉強を始めて5ヶ月目の初心者ですのでどうぞよろしくご教示願います。

テキストファイルに16進数で書かれている数字をバイナリモードで読み込み「BITMAP」という文字を見つけたら「□」と「■」を使って数字の横に白黒ビットマップの表示を始め、「ENDCHAR」という文字を見つけたら終了するというプログラムを作っています。

読み込みたいファイルはこのようなものです。

STARTCHAR 2421
ENCODING 9249
SWIDTH 480 0
DWIDTH 7 0
BBX 7 7 0 -1
BITMAP
0000
0000
2000
f800
7000
b800
6800
ENDCHAR

最後に読み込みに成功したかをフラグを立てて判断するようにしたいです。ファイルを読み込むことはできましたがそれ以上がどうしても書けません。どなたかお分かりになる方いらっしゃいましたらよろしくお願い致します。

開発環境は
WindowsXP
VisualC++V6.0です。

Aベストアンサー

★行単位ではファイルを読み込めるのですよね。
・それならば、行単位で読み込んだ文字列を1行ずつ調べていきます。
 おおよそのアルゴリズムは
 (1)行単位で文字列を取得します。→『fgets』関数など
 (2)『BITMAP』文字列を探します。→『strcmp』関数などで比較
 (3)『BITMAP』文字列以降の文字列は16進文字列なのでこれを整数に変換します。→『strtol』関数など
 (4)変換した整数を1ビットずつ調査して、ON/OFFを■/□で出力します。→ビットANDする(&)演算子
 (5)『ENDCHAR』文字列が見つかったらば処理を終了します。
 となります。
・16進数の文字列を整数に変換する方法は『strtol』関数や『strtoul』関数を利用します。
 まぁ、とにかく下のサンプルをどうぞ。

サンプル:
char buff[ 256 ];
int flag = 0; ←フラグ

while ( fgets(buff,sizeof(buff),fp) != NULL ){
 if ( !strcmp(buff,"ENDCHAR\r\n") ){
  break; ←おわり
 }
 if ( flag ){
  /*
  ここに16進文字列を整数に変換して、ON/OFFの状態を■/□で出力します。
  */
 }
 else if ( !strcmp(buff,"BITMAP\r\n") ){
  flag = 1; ←次の行からは16進文字列を解釈するためにセット
 }
}
if ( flag ){ ←ここで『読み込みに成功したかのフラグを判断』しています。
 printf( "成功。\n" );
}
else{
 printf( "失敗!\n" );
}

最後に:
・16進文字列を整数に変換する『strtol』関数の使い方は
 long strtol( const char *str, char **endptr, int base );
 ですので『value = strtol( buff, NULL, 16 );』とすると value 変数に変換された整数が
 格納されます。value は long 型です。int 型変数に代入する場合はキャストして下さい。
・整数から1ビットのON/OFFを調べるにはビットANDの(&)演算子を使います。
 value & 0x0001⇒1ビット目のON/OFFが分かる
 value & 0x0002⇒2ビット目のON/OFFが分かる
 value & 0x0004⇒3ビット目のON/OFFが分かる
 value & 0x0008⇒4ビット目のON/OFFが分かる
 これをシフト演算と組み合わせるとループ文などで記述できます。
 for ( i = 0 ; i < 16 ; i++ ){ ←16ビットを処理するので16
  if ( value & 0x8000 ){ ←最上位のビットを調査
   /* ビットON→■を出力 */
  }
  else{
   /* ビットOFF→□を出力 */
  }
  value <<= 1; ←左シフト
 }
・以上。参考に!

参考URL:http://www9.plala.or.jp/sgwr-t/lib/strtol.html

★行単位ではファイルを読み込めるのですよね。
・それならば、行単位で読み込んだ文字列を1行ずつ調べていきます。
 おおよそのアルゴリズムは
 (1)行単位で文字列を取得します。→『fgets』関数など
 (2)『BITMAP』文字列を探します。→『strcmp』関数などで比較
 (3)『BITMAP』文字列以降の文字列は16進文字列なのでこれを整数に変換します。→『strtol』関数など
 (4)変換した整数を1ビットずつ調査して、ON/OFFを■/□で出力します。→ビットANDする(&)演算子
 (5)『ENDCHAR』文字列が見つかったらば...続きを読む

Q変数のビット列

char型の変数numに
num = 128 + 64 + 16;
と入力した時、numの中身は、
11010000
となっているのか、
00001101
となっているのか(最下位桁が右か左か)調べたいのですが、格納されている状態(バイトオーダーが使用される前の状態)で表示する命令を教えていただけませんでしょうか。
最終的に、char型の下位7bitを使って数値処理をしたく、その場合には、
num = num << 1;
と、
num = num >> 1;
のどちらにすればいいのか、変わってくるかと思います。
ご回答の程お願いします。

Aベストアンサー

型によらず整数の内部ビット表現は上位ビット←→下位ビットの順に並べることになっています。したがって
<<:左シフト演算子は桁上げ
>>:右シフト演算子は桁下げ
です。

JIS X3010:2003にも規格書6.5.7章 ビット単位のシフト演算子の項に、

E1<<E2の...結果の値はE1×2^E2の、結果の型で表現可能な最大値より1大きい値を法とする剰余とする。...E1>>E2の...結果の値はE1/2^E2の商の整数部分とする。...

となっています。

Qビット列を表示するプログラム

C言語の問題でビット列を表示するプログラムが全くできません。
どなたか分かる人はどうか知恵を貸してください。

ユーザが整数を入力すると、その整数をINT型の変数に入れ、そのビット列を表示するプログラム。
ただ、INT型のビット数は環境によって変わる可能性があるため、sizeof()関数を利用してINT型の変数のビット数を求め、そのビット数分だけ表示する。

Aベストアンサー

sizeof()関数は、sizeof()演算子ですね。

ループで、1ビットを論理積評価して結果を逆順に表示するのが
簡単ですが、一例として以下も参考にしてみて下さい。

<リスト>
#include <stdio.h>

int main()
{
int i; … 1
unsigned int mask=0x80<<(8*(sizeof(i)-1)); … 2

printf("数値?"); … 3
scanf("%d",&i); … 4
do printf("%1d",i&mask?1:0); while (mask>>=1); … 5
printf("\n"); … 6
return 0; … 7
}

<説明>
1.int 型の変数宣言
2.1オクテット(最小バイトビット数が8ビット)
での最上位ビットを算出する。
つまり、
1オクテット(固定8ビット)の最上位ビットの 0x80 を
(バイトサイズ - 1)× 8 回
左シフトすれば良いわけです。
※2によりビットマスクが算出できます。
3、4.整数入力
5.ビットマスクを最上位から最下位までずらしてそれぞれの
入力整数値とビットマスクの論理積が 0 であれば目的ビットは 0、
論理積が 0以外 であれば目的ビットは 1 と出力します。

たとえば、
int : 2バイト
入力整数値(10進数):32768(16進で 0xF0F0)
(2進で 11110000 11110000)の時、
ビットマスク = 0x80 を (sizeof(int) - 1) * 8 回分、左シフト
= 0x80 を(2 - 1) * 8 回分、左シフト
= 0x8000 (2進で、10000000 00000000)
1回目:11110000 11110000 & 10000000 00000000 = 10000000 00000000
… 10進数で 0 以外なので「1」を表示(表示結果:1)
ビットマスクを右にずらすので、mask = 01000000 00000000
2回目:11110000 11110000 & 01000000 00000000 = 01000000 00000000
… 10進数で 0 以外なので「1」を表示(表示結果:11)
ビットマスクを右にずらすので、mask = 00100000 00000000


16回目:11110000 11110000 & 00000000 00000001 = 00000000 00000000
… 10進数で 0 なので「0」を表示(表示結果:11110000 11110000)
ビットマスクを右にずらすので、mask = 0000000 00000000
ループはマスクが 0 になったら抜けるので終了です

sizeof()関数は、sizeof()演算子ですね。

ループで、1ビットを論理積評価して結果を逆順に表示するのが
簡単ですが、一例として以下も参考にしてみて下さい。

<リスト>
#include <stdio.h>

int main()
{
int i; … 1
unsigned int mask=0x80<<(8*(sizeof(i)-1)); … 2

printf("数値?"); … 3
scanf("%d",&i); … 4
do printf("%1d",i&mask?1:0); while (mask>>=1); … 5
printf("\n"); … 6
return 0; … 7
}

<説明>
1.int 型の変数宣言
2.1オクテット(最小バ...続きを読む

Qchar型でビット列表示

char型の変数にビット配列を代入しそれを文字として出力させたいのです。
どこが間違っているのか分かりませんが一応流れを書いたプログラムを載せておきます。

char binary = 0;
int i;

for(i=0;i<8;i++){
if(省略) binary = binary & 11111110;
else binary = binary | 00000001;
binary = binary << 1;
}
printf("実行結果 %c",binary);


実行結果 00110110

というように最下位ビットに0か1を代入し、左シフトをし、というのを繰り返しprintf("%c",binary)でビット列を表示させたいのですが、これを実行すると結果は文字化けしたようなものが表示されます。
charの配列を作ってビット列を表示させるやり方はわかるのですが、学校の課題みたいなもので配列を使ってはいけないみたいなのです。
教科書を読んでも分からないので困っています。
よろしくお願いします。

char型の変数にビット配列を代入しそれを文字として出力させたいのです。
どこが間違っているのか分かりませんが一応流れを書いたプログラムを載せておきます。

char binary = 0;
int i;

for(i=0;i<8;i++){
if(省略) binary = binary & 11111110;
else binary = binary | 00000001;
binary = binary << 1;
}
printf("実行結果 %c",binary);


実行結果 00110110

というように最下位ビットに0か1を代入し、左シフトをし、というのを繰り返しprintf("%c",binary)でビット列を表示さ...続きを読む

Aベストアンサー

No3 です。
今度は、「省略」の解明(◆)です。
「解明」してどうなるの、と問われればそれまてですが、何かの参考になればと。
-------------------------------------
むりくり、

>実行結果 00110110

になるように、プログラムしてみました。
-------------------------------------
#include <stdio.h>

#define un_char unsigned char
void main()
{
int i;
un_char cBinary = 0x00, cWork;

for( i = 0; i < 8; i++ ){

if( ( 0 == i ) || ( 1 == i ) || ( 2 == i ) || ( 5 == i ) ) cBinary &= (un_char)0xFE; // ◆

elsecBinary |= 0x01;

cBinary <<= 1;
}
for( i = 0; i < 8; i++ ){ // 1ビットずつの表示(2進風?)

cWork = cBinary >> ( 7 - i );
cWork &= 0x01;
cWork += 0x30;

printf( "%c", cWork );
}
}
★重要
1 と「表示」したいとき、%c フォーマット指定子をもちいて '1' (0x31)を出力
0 と「表示」したいとき、%c フォーマット指定子をもちいて '0' (0x30)を出力
-----------------------------------------
>これを実行すると結果は文字化けしたようなものが表示されます。

★理解できたのではないでしょうか(前の回答のアスキーコード表と併せて)。

No3 です。
今度は、「省略」の解明(◆)です。
「解明」してどうなるの、と問われればそれまてですが、何かの参考になればと。
-------------------------------------
むりくり、

>実行結果 00110110

になるように、プログラムしてみました。
-------------------------------------
#include <stdio.h>

#define un_char unsigned char
void main()
{
int i;
un_char cBinary = 0x00, cWork;

for( i = 0; i < 8; i++ ){

if( ( 0 == i ) || ( 1 == i ) || ( 2 == i ) || ( 5 == i ) ) ...続きを読む

Qビット列を走査するプログラムの関数化

char型の変数に0or1を入れて擬似的にビット列にした配列をLSBからMSBまで走査し、一致したらループを抜け終了するプログラムをCで書きたいと思っています。
他のプログラムでも使いまわし、かつ見やすくするためにこの部分を関数化したいのです。ソースにはbreakを使っているのですが、当然ながらbreakはforかwhile内で使わないとダメだと思いますが、ソース作成の都合上、for文は関数内に入れたくないのです。
(つまり、条件分岐を関数化したものをfor文内で用いたい)

うまい方法が思いつかずに困っています。もし良い方法をお気づきの方がおられたらご助力下さい。

//===============================================//
//=================以下ソース====================//
//===============================================//
//ビット配列correct_ciphertextとPbinを比較するプログラム
//LSBからMSBまで順に走査を行い、違うビットが出てきた時点でbreakし、走査を止める
//Pbinは固定値を与えている
#include <stdio.h>
#include <string.h>

unsigned int mes[2];
unsigned int key[2];
char Pbin[64];
char Kbin[64];
char ciphertext[64] = { 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0};

void ConvertPtextToBin_ForHost(unsigned int mes[]){
unsigned int tmp_mes[2] = {mes[0], mes[1]};
int i, j;
for(j=0;j<=1;j++){
for(i=0;i<=31;i++){
Pbin[j*32 + 31-i] = tmp_mes[j] % 2;
tmp_mes[j] = tmp_mes[j] / 2;
}
}
}


int main(int argc, char *argv[]){
//initialize
mes[0] = 0x00000000;
mes[1] = 0x00000000;

int i, j, k;
int x=0, y=0;
while(1){
printf("mes[1] = %d\n", mes[1]);
ConvertPtextToBin_ForHost(mes);
for(i=0; i<64; i++){
printf("%d", Pbin[i]);
if((i+1)%8 == 0)
printf(" ");
}
printf("\n");

//*************************
//ビット走査
//*************************
for(k=0; k<64; k++){
if( (ciphertext[63-k] == Pbin[63-k]) ){
//同じビットであれば、次のビットを走査する
}else{
printf("Error\n");//後ろから走査していって、1ビットでも違うものがあれば違うビット列と判断する
break;
}
}
//ここに来たら違うビット列だったということ
if(k != 64){
mes[1]++;
printf("Not match ciphertext... %dth bit didn't match. (0bit:LSB)\n", k);
printf("This was %d*%dth Search...\n\n", y, x);
x++;
if(x>=65535){i=0; y++;}
}else{
//k=64つまり、最後のビットまで同じビットだったということ⇒つまり、「発見」
printf("Match ciphertext\n");
printf("This was %d*%dth Search...\n\n", y, x);
break;
}
//***********************
//ビット走査の終了
//***********************
}
}

char型の変数に0or1を入れて擬似的にビット列にした配列をLSBからMSBまで走査し、一致したらループを抜け終了するプログラムをCで書きたいと思っています。
他のプログラムでも使いまわし、かつ見やすくするためにこの部分を関数化したいのです。ソースにはbreakを使っているのですが、当然ながらbreakはforかwhile内で使わないとダメだと思いますが、ソース作成の都合上、for文は関数内に入れたくないのです。
(つまり、条件分岐を関数化したものをfor文内で用いたい)

うまい方法が思いつかずに困ってい...続きを読む

Aベストアンサー

こんな感じでどうでしょうか
一応動作確認はしてあります

//// ソースはここから ///////////////////////////////////////////
// ChkBit.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//

#include "stdafx.h"

//ビット配列correct_ciphertextとPbinを比較するプログラム
//LSBからMSBまで順に走査を行い、違うビットが出てきた時点でbreakし、走査を止める
//Pbinは固定値を与えている
#include <stdio.h>
#include <string.h>

// 扱う最大ビット長
#define MAX_BIT_LENGTH64
// ブロック化するビット長
#define BLOCK_LENGHT8


unsigned int mes[2];
unsigned int key[2];
char Pbin[MAX_BIT_LENGTH];
char Kbin[MAX_BIT_LENGTH];
char ciphertext[MAX_BIT_LENGTH] =
{ 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0};

// 指定された配列(bitをエミュレート)の指定ビットに値を設定する
static void SetBit(char Dest[], int Pos, int Bit)
{
Dest[Pos] = Bit;
}


static void ConvertPtextToBin_ForHost(unsigned int mes[])
{
unsigned int tmp_mes[2] = {mes[0], mes[1]};
int i, j;
for(j = 0;j <= 1;j++)
{
for(i = 0;i <= 31;i++)
{
SetBit(Pbin, j * 32 + 31 - i, tmp_mes[j] & 0x01);
tmp_mes[j] >>= 1;
}
}

}

// 8ビットを1ブロックとして区切りながら表示する
static void FmtDisp(char sec[])
{
int i;
for (i = 0; i< MAX_BIT_LENGTH; i++)
{
printf("%d", Pbin[i]);
if (!((i+1) % BLOCK_LENGHT))
printf(" ");
}
printf("\n");
}

// ビットパターン配列(char配列)を比較し
// 配列[0]がMSB 配列[MAX_BIT_LENGTH - 1]がLSBとする
// LSBから順にサーチするものとする
// 最初に違いが見つかったビットの番号(MSB = 0)を返す
// 全ビット一致した場合はLengthを戻す
static int FindDiffBitNumber(char buf1[], char buf2[], int Length)
{
int i;
for (i = 0; i < Length; i++)
{
int n;

n = Length - 1 - i;// LSBを基準としたビット位置
if (buf1[n] != buf2[n])
return i;
}

return Length;
}

// ビット走査を行う
// 違うなら0, 同一なら0以外を戻す
static int SearchBit(char buf1[], char buf2[], int Length,
unsigned int mes[], int* x, int* y)
{
long n;

n = FindDiffBitNumber(buf1, buf2, Length);
if(n < Length)
{
// 違うビットが検出された場合
mes[1]++;
printf("Not match ciphertext... %dth bit didn't match. (0bit:LSB)\n", n);
printf("This was %d*%dth Search...\n\n", *y, (*x)++);

if (*x >= 65535)
{
(*y)++;
}

return 0;
}
else
{
// 同一だった場合
printf("Match ciphertext\n");
printf("This was %d*%dth Search...\n\n", *y, *x);
return 1;
}
}


int main(int argc, char *argv[])
{
int x = 0, y = 0;


//initialize
mes[0] = 0x00000000;
mes[1] = 0x00000000;

do
{
printf("mes[1] = %d\n", mes[1]);
ConvertPtextToBin_ForHost(mes);

// 8ビットを1ブロックとして区切りながら表示する
FmtDisp(Pbin);

} while (!SearchBit(ciphertext, Pbin, MAX_BIT_LENGTH, mes, &x, &y)) ;
}

/// ソースはここまで ///////

x, yはSearchBit()関数内のstatic変数として、
パラメータから除くことも考えました。

しかし、 SearchBit()が使いまわされることを考えると、
x, yのリセット処理が必要になります。

この辺は単なる関数化だけでなく、
"モジュール化"も考えたほうがいいかとも思います。
(C++のクラス化も大いにありです)
そして
x, yはstatic変数(C++ではメンバ変数)とし、
SearchBit()のパラメータから除く。
代わりにx,yをリセットする関数を設ける
こちらのほうが使いやすいと思います。

こんな感じでどうでしょうか
一応動作確認はしてあります

//// ソースはここから ///////////////////////////////////////////
// ChkBit.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//

#include "stdafx.h"

//ビット配列correct_ciphertextとPbinを比較するプログラム
//LSBからMSBまで順に走査を行い、違うビットが出てきた時点でbreakし、走査を止める
//Pbinは固定値を与えている
#include <stdio.h>
#include <string.h>

// 扱う最大ビット長
#define MAX_BI...続きを読む


人気Q&Aランキング

おすすめ情報