【掲示板ご利用上の注意】

 ※題名は具体的に!
 ※学校の課題の丸投げ禁止!
 ※ソースの添付は「HTML変換ツール」で字下げ!
 ※返信の引用は最小限に!
 ※環境(OSとコンパイラ)や症状は具体的に詳しく!
 ※返信付き投稿の削除は禁止!
 ※マルチポスト(多重投稿)は慎んで!

 詳しくはこちら


本当はこんなに大きく書きたくはないのですが、なかなか守っていただけなくて…。
 守ってくださいね。お願いします。(by管理人)

C言語ソース⇒HTML形式ツール掲示板2こちら


管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.21978

2値画像のマージン除去と拡大について
投稿者---Sur(2005/07/17 10:28:23)


2値ビットマップデータ(黒=1, 白=0)を2進でunsigned char型の配列内に記憶しています。
また、その画像の高さと幅、画像配列をセットにした構造体PIXELIMAGEを定義しています。
この画像から白マージンを取り除き、元の大きさに拡大するという関数int TrimWhitePIXIMG(PIXELIMAGE*)を作っています。

Bresenhamのアルゴリズムなども用いているのですが、どうしても実行速度の遅さがネックとなってしまっています。改善点がどこにあるか、ご教示頂きたく投稿しました。実際に制作しているプログラムのソースは次のような物です。


この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> 2値画像のマージン除去と拡大について(続き) 21979 Sur 2005/07/17 10:29:08
<子記事> 2値画像のマージン除去と拡大について(続き) 21980 Sur 2005/07/17 10:29:41


No.21979

2値画像のマージン除去と拡大について(続き)
投稿者---Sur(2005/07/17 10:29:08)


#include <stdio.h>
#include <malloc.h>

typedef unsigned char BYTE;
typedef unsigned short PIXSIZE;

// ピクセルイメージを記録する構造体
typedef struct _tagPIXELIMAGE
{
    BYTE**    img;    // 画像部(binaryデータ)
    PIXSIZE     height;  // 高さ
    PIXSIZE     width;    // 幅
}PIXELIMAGE;

int AllocPIXELIMAGE(PIXELIMAGE*, PIXSIZE, PIXSIZE);
/********************************************************************************
    PIXELIMAGE構造体の画像メモリを確保し、メンバをリセットする。
    引数:
        PIXELIMAGE* pix...      確保したいPIXELIMAGE構造体へのポインタ
        PIXSIZE  height...        確保したい高さ
        PIXSIZE  width...  確保したい幅
    戻り値:
        成功時...          0
        失敗時...          (negative number)
            引数が不正...            -1
            メモリ確保失敗...    -2
********************************************************************************/


int FreePIXELIMAGE(PIXELIMAGE*);
/********************************************************************************
    PIXELIMAGE構造体の画像メモリを開放し、メンバをリセットする。
    引数:
        PIXELIMAGE* pix...      開放したいPIXELIMAGE構造体へのポインタ
    戻り値:
        成功時...          0
        失敗時...          (negative number)
            引数が不正...            -1
            構造体メンバが不正...    -2
********************************************************************************/

int TrimWhitePIXIMG(PIXELIMAGE*);



この投稿にコメントする

削除パスワード

No.21980

2値画像のマージン除去と拡大について(続き)
投稿者---Sur(2005/07/17 10:29:41)


int main(int argc, char *argv[])
{
    PIXELIMAGE pix;
    PIXSIZE i, j, k;
    BYTE c;
    BYTE tmp[8] = {
        0x00,
        0x00,
        0x00,
        0x00,
        0x01,
        0x01,
        0x01,
        0x03
    };

    AllocPIXELIMAGE(&pix, 8, 8);

    for(i=0;i<8;i++)
        pix.img[i][0] = tmp[i];

    TrimWhitePIXIMG(&pix);

    for(i=0;i<pix.height;i++)
    {
        for(j=0;j<(pix.width << 3) + (pix.width&0x7)?1:0;j++)
        {
            c = 0x80;
            for(k=0;k<8 && (j<<3)+k <pix.width;k++)
            {
                if(pix.img[i][j] & c)
                    printf("1");
                else
                    printf("0");
                c >>= 1;
            }
        }
        printf("\n");
    }

    FreePIXELIMAGE(&pix);

    return 0;
}


int TrimWhitePIXIMG(PIXELIMAGE* src)
{
    PIXSIZE i, j, k, l=0;
    BYTE    c;
    PIXSIZE top = src->height, bottom = 0, right = 0, left = src->width, width, height, v_pos, h_pos, x = 0, y = 0;
    BYTE **tmp = (BYTE**)calloc(sizeof(BYTE*), src->height);

    for(i=0;i<src->height;i++)
    {
        tmp[i] = (BYTE*)calloc(sizeof(BYTE), src->width);
        for(j=0;j<(src->width>>3)+((src->width&0x7)?1:0);j++)
        {
            c = 0x80;
            for(k=0;k<8&&(j<<3)+k<src->width;k++)
            {
                if((tmp[i][(j<<3)+k] = ((src->img[i][j] & c)?1:0)))
                {
                    if(i < top)
                        top = i;
                    if(i > bottom)
                        bottom = i;
                    if((j<<3)+k < left)
                        left = (j<<3)+k;
                    if((j<<3)+k > right)
                        right = (j<<3)+k;
                }
                c >>= 1;
            }
        }
    }

    width = right - left + 1;
    height = bottom - top + 1;
    if(width == src->width && height == src->height)
        return 0;

    v_pos = height >> 1;
    y = top;
    for(i=0;i<src->height;i++)
    {
        h_pos = width >> 1;
        x = left;
        for(j=0;j<(src->width>>3) + (src->width&0x7)?1:0;j++)
        {
            src->img[i][j] = 0;
            for(k=0;k<8&&(j<<3)+k<src->width;k++)
            {
                src->img[i][j] <<= 1;
                src->img[i][j] |= tmp[y][x];

                h_pos += width;
                if(h_pos > src->width)
                {
                    x++;
                    h_pos -= src->width;
                }
            }

        }

        v_pos += height;
        if(v_pos > src->height)
        {
            y++;
            v_pos -= src->height;
        }
    }
    return 0;
}

int AllocPIXELIMAGE(PIXELIMAGE* pix, PIXSIZE height, PIXSIZE width)
/********************************************************************************
    PIXELIMAGE構造体の画像メモリを確保し、メンバをセットする。
    引数:
        PIXELIMAGE* pix...      確保したいPIXELIMAGE構造体へのポインタ
        PIXSIZE  height...        確保したい高さ
        PIXSIZE  width...  確保したい幅
    戻り値:
        成功時...          0
        失敗時...          (negative number)
            引数が不正...            -1
            メモリ確保失敗...    -2
********************************************************************************/
{
    PIXSIZE i;

    // 引数の不正チェック
    if( pix    == (PIXELIMAGE*)NULL ||
        height  == (PIXSIZE)0 ||
        width   == (PIXSIZE)0)
            return -1;

    // メモリ列の確保
    if((pix->img = (BYTE**)calloc(sizeof(BYTE*), height))==NULL)
        return -2;

    // メモリの確保
    for(i=0;i<height;i++)
        if((pix->img[i] = (BYTE*)calloc(sizeof(BYTE), (int)(width>>3) + ((width&0x7)?1:0)))==NULL)
            return -2;

    // メンバセット
    pix->height = height;
    pix->width = width;

    return 0;
}

int FreePIXELIMAGE(PIXELIMAGE* pix)
/********************************************************************************
    PIXELIMAGE構造体の画像メモリを開放し、メンバをリセットする。
    引数:
        PIXELIMAGE* pix...      開放したいPIXELIMAGE構造体へのポインタ
    戻り値:
        成功時...          0
        失敗時...          (negative number)
            引数が不正...            -1
            構造体メンバが不正...    -2
********************************************************************************/
{
    PIXSIZE i;
    // 引数の不正チェック
    if(pix == (PIXELIMAGE*)NULL)
        return -1;

    // 構造体メンバの不正チェック
    if(pix->height == 0 || pix->width == 0 || pix->img == NULL)
        return -2;

    // メモリ開放
    for(i=0;i<pix->height;i++)
    {
        if(pix->img[i] == NULL)
            return -2;
        free(pix->img[i]);
    }

    // メモリ列開放
    free(pix->img);

    // メンバリセット
    pix->height = 0;
    pix->width  = 0;

    return 0;
}




この投稿にコメントする

削除パスワード

No.21982

Re:2値画像のマージン除去と拡大について(続き)
投稿者---isshi(2005/07/17 22:32:12)


まず、マージンを調べているところについてですが、
画像の全ピクセルを調べる必要はありません。

上から1行ずつ見ていって最初に黒があった行がtopとなります。
このときいちいち1バイト中の各ビットを見る必要はなく、
1バイトが0以外なら黒があるとわかります。
同様に下から見ていけばbottomが決まります。

左(右)の場合は左(右)から1列ずつ(1バイトずつ)0以外かどうか見ていき、
0以外なら各ビットを見て左端(右端)を調べます。
このとき、top, bottomはわかっているのでその間だけを調べればよいです。


次に、拡大しているところについては、
http://www2.starcat.ne.jp/~fussy/algo/algo4-2.htm
の1番下のソースの
/* 先にX方向のループでの増加分を計算 */
を参考にしてみてはどうでしょうか?


ところで、実際の画像サイズ、現状の処理時間、目標の処理時間は
どうなっていますか?



この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧