いま、C言語を使って画像処理のプログラミングを行っているのですが、少し行き詰ってしまっているので皆様のお力をお借りしたいです。
処理内容としては、画像を二値化(仮に黒を0、白を1とします)したあとに、その二値化した画像をY軸方向(画像を上から)からスキャンし、
その列で一番初めの0の部分の座標(X.Y)を求めて、その座標をもとに横からスキャンし、先ほど求めた座標のひとつ前にある座標の値を変える(0の場合1に、1の場合0にする)
という処理なのですが画像の二値化まではできたのですが、その後の部分の作成の仕方がわからないので、アドバイスをよろしくお願いいたします。
以下、ソースコードです。(二値化まで)
#include <stdio.h>
#include <process.h>
#define Y_SIZE 512 // 処理できる最大画像
#define X_SIZE 512
#define HIGH 255 // 画像の最大強度値
#define LOW 0 // 画像の最小強度値
#define LEVEL 256 // 画像の強度レベル値
// BMPファイルのフォーマットに従って用意した変数
typedef unsigned short WORD;
typedef unsigned long DWORD;
WORD bfType;
DWORD bfSize;
WORD bfReserved1,
bfReserved2;
DWORD bfOffBits;
DWORD biSize,
biWidth, biHeight;
WORD biPlanes,
biBitCount;
DWORD biCompression,
biSizeImage,
biXPelsPerMeter,
biYPelsPerMeter,
biClrUsed,
biClrImportant;
unsigned char image_in[Y_SIZE][X_SIZE][3]; // 入力カラー画像配列
unsigned char image_out[Y_SIZE][X_SIZE][3]; //出力カラー画像配列
unsigned char image_bw[Y_SIZE][X_SIZE]; //濃淡画像配列
unsigned char data_rgb[Y_SIZE][X_SIZE][3]; // RGB画像配列
void readBMP(
char *filename, // BMPファイル名
unsigned char image[Y_SIZE][X_SIZE][3] // 24ビットRGB画像配列
)
{
FILE *fp;
int i, j, k;
// ファイルオープン
if ((fp = fopen(filename, "rb"))==NULL) {
printf("readBmp: Open error!\n");
exit(1);
}
printf("input file : %s\n", filename);
// ヘッダー情報読み込む
fread(&bfType, sizeof(bfType), 1, fp);
fread(&bfSize, sizeof(bfSize), 1, fp);
fread(&bfReserved1, sizeof(bfReserved1), 1, fp);
fread(&bfReserved2, sizeof(bfReserved2), 1, fp);
fread(&bfOffBits, sizeof(bfOffBits), 1, fp);
fread(&biSize, sizeof(biSize), 1, fp);
fread(&biWidth, sizeof(biWidth), 1, fp);
fread(&biHeight, sizeof(biHeight), 1, fp);
fread(&biPlanes, sizeof(biPlanes), 1, fp);
fread(&biBitCount, sizeof(biBitCount), 1, fp);
fread(&biCompression, sizeof(biCompression), 1, fp);
fread(&biSizeImage, sizeof(biSizeImage), 1, fp);
fread(&biXPelsPerMeter, sizeof(biXPelsPerMeter), 1, fp);
fread(&biYPelsPerMeter, sizeof(biYPelsPerMeter), 1, fp);
fread(&biClrUsed, sizeof(biClrUsed), 1, fp);
fread(&biClrImportant, sizeof(biClrImportant), 1, fp);
// RGB画像データ読み込む
for (i=0; i<(int)biHeight; i++)
for (j=0; j<(int)biWidth; j++) {
for (k=0; k<3; k++) {
//fread(&image[i][j][2-k], 1, 1, fp);
fread(&image[biHeight-i][j][2-k], 1, 1, fp);
}
}
fclose(fp);
}
void writeBMP(
unsigned char image[Y_SIZE][X_SIZE][3],
char *filename )
{
FILE *fp;
int i, j, k;
// ファイルオープン
if ((fp = fopen(filename, "wb"))==NULL) {
printf("writeBmp: Open error!\n");
exit(1);
}
printf("output file : %s\n", filename);
// ヘッダー情報
fwrite(&bfType, sizeof(bfType), 1, fp);
fwrite(&bfSize, sizeof(bfSize), 1, fp);
fwrite(&bfReserved1, sizeof(bfReserved1), 1, fp);
fwrite(&bfReserved2, sizeof(bfReserved2), 1, fp);
fwrite(&bfOffBits, sizeof(bfOffBits), 1, fp);
fwrite(&biSize, sizeof(biSize), 1, fp);
fwrite(&biWidth, sizeof(biWidth), 1, fp);
fwrite(&biHeight, sizeof(biHeight), 1, fp);
fwrite(&biPlanes, sizeof(biPlanes), 1, fp);
fwrite(&biBitCount, sizeof(biBitCount), 1, fp);
fwrite(&biCompression, sizeof(biCompression), 1, fp);
fwrite(&biSizeImage, sizeof(biSizeImage), 1, fp);
fwrite(&biXPelsPerMeter, sizeof(biXPelsPerMeter), 1, fp);
fwrite(&biYPelsPerMeter, sizeof(biYPelsPerMeter), 1, fp);
fwrite(&biClrUsed, sizeof(biClrUsed), 1, fp);
fwrite(&biClrImportant, sizeof(biClrImportant), 1, fp);
// ビットマップデータ
for (i=0; i<(int)biHeight; i++)
for (j=0; j<(int)biWidth; j++) {
for (k=0; k<3; k++) {
fwrite(&image[biHeight-i][j][2-k], 1, 1, fp);
}
}
fclose(fp);
}
void BMPto256BW(
unsigned char image[Y_SIZE][X_SIZE][3],
unsigned char image_bw[Y_SIZE][X_SIZE] )
{
int y, x, a;
for (y=0; y<(int)biHeight; y++)
for (x=0; x<(int)biWidth; x++) {
a = (int)(0.3*image[y][x][0] + 0.59*image[y][x][1] + 0.11*image[y][x][2]);
if (a<LOW) a = LOW;
if (a>HIGH) a = HIGH;
image_bw[y][x] = a;
}
}
void BWto24BMP(
unsigned char image_bw[Y_SIZE][X_SIZE],
unsigned char image[Y_SIZE][X_SIZE][3] )
{
int y, x, a;
for (y=0; y<(int)biHeight; y++)
for (x=0; x<(int)biWidth; x++) {
a = image_bw[y][x];
image[y][x][0] = a;
image[y][x][1] = a;
image[y][x][2] = a;
}
}
void toBinary(
int atai,
unsigned char image_bw[Y_SIZE][X_SIZE] )
{
int y, x;
for (y=0; y<(int)biHeight; y++)
for (x=0; x<(int)biWidth; x++) {
if(image_bw[y][x] >= atai) image_bw[y][x]=HIGH;
else image_bw[y][x] = LOW;
}
}
void imageCopyBW(
unsigned char image1[Y_SIZE][X_SIZE],
unsigned char image2[Y_SIZE][X_SIZE] )
{
int x, y;
for (y=0; y<(int)biHeight; y++)
for (x=0; x<(int)biWidth; x++)
image2[y][x] = image1[y][x];
}
void main(void)
{
char input[100], output[100];
int intensity;
printf("入力画像ファイル名(*.bmp):"); scanf("%s", input);
readBMP(input, image_in); // 画像の入力,RGB24ビットカラーBMP画像を配列に格納
//画像処理2:白黒変換
BMPto256BW(image_in, image_bw); // RGBカラー画像を白黒画像に変換
BWto24BMP(image_bw, image_out); // 単チャンネル白黒画像を3チャンネルBMP標準フォーマットへ変換
printf("白黒出力画像ファイル名(output.bmp):"); scanf("%s", output);
writeBMP(image_out, output); // 白黒画像出力
//画像処理3:2値化
printf("2値化画像の閾値(0~255):"); scanf("%d", &intensity);
toBinary(intensity,image_bw);
BWto24BMP(image_bw, image_out);
printf("2値化出力画像ファイル名(*.bmp):"); scanf("%s", output);
writeBMP(image_out, output); // 白黒画像出力
}