最終更新: mikk_ni3_92 2008年04月19日(土) 18:35:09履歴
現在地 >> メニュー >> サンプルコード::OpenCV >> OpenCV::読み込みテスト >> OpenCV::読み込みテスト2
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cv.h>
#include <highgui.h>
using namespace std;
/*** [データ構造] ***/
typedef struct
{
unsigned char* imageData;
unsigned int bpp;
unsigned int width;
unsigned int height;
bool RLE_flag;
unsigned int imageSize;
unsigned int color_num;
}TGA_IMG;
char *tgafilename ="image.tga";
/************* [プロトタイプ宣言] *******************/
void LoadTGA(char *filename, TGA_IMG *texture);
void LoadUncompressedTGA(char *filename, FILE *fTGA, TGA_IMG *texture);
void LoadCompressedTGA(char *filename, FILE *fTGA, TGA_IMG *texture);
void SET_TGA_INFOMATION(TGA_IMG *texture,FILE *fTGA);
/**************** [メイン関数] *********************/
int main(int argc, char**argv)
{
TGA_IMG *tga_img;
tga_img = new TGA_IMG();
LoadTGA(tgafilename,tga_img);
IplImage *imgA;
CvSize window_size;
window_size.width = tga_img->width;
window_size.height= tga_img->height;
imgA = cvCreateImage(window_size,IPL_DEPTH_8U,3);
memcpy(imgA->imageData,tga_img->imageData,tga_img->width*tga_img->height*3);
if(tga_img->RLE_flag == true)
{
cvCvtColor(imgA, imgA, CV_RGB2BGR);
}
cvFlip(imgA,NULL,0);
delete [] tga_img->imageData;tga_img->imageData=NULL;
delete tga_img;tga_img=NULL;
cvNamedWindow("load tga image",CV_WINDOW_AUTOSIZE);
cvShowImage("load tga image",imgA);
cvWaitKey(0);
cvReleaseImage( & imgA);
cvDestroyAllWindows();
return 0;
}
/*************** ここから各種関数 ********************/
void LoadTGA(char *filename, TGA_IMG *texture)
{
FILE *fTGA;
fTGA = fopen(filename,"rb");
if(fTGA ==NULL)
{
puts("can't open file");
exit(0);
}
/** 最初の12バイトを読み込む **/
unsigned char tgaheader[12];
if(fread(&tgaheader, sizeof(tgaheader), 1, fTGA) == 0)
{
puts("can't read header");
exit(0);
}
unsigned char uTGAcompare[12] = {0,0, 2,0,0,0,0,0,0,0,0,0};
unsigned char cTGAcompare[12] = {0,0,10,0,0,0,0,0,0,0,0,0};
/** 圧縮か未圧縮かで場合分け **/
if(memcmp(uTGAcompare, &tgaheader, sizeof(tgaheader)) == 0)
{
puts("this file is uncompressed");
LoadUncompressedTGA(filename, fTGA,texture);
}
else if(memcmp(cTGAcompare, &tgaheader, sizeof(tgaheader)) == 0)
{
puts("this file is compressed");
LoadCompressedTGA(filename, fTGA,texture);
}
else
{
puts("wrong!");
}
fclose(fTGA);fTGA=NULL;
}
/**************** [未圧縮TGAの読み込み] *****************/
void LoadUncompressedTGA(char *filename, FILE *fTGA, TGA_IMG *texture)
{
texture->RLE_flag = false;
SET_TGA_INFOMATION(texture,fTGA); //ヘッダ情報取得
/** データ読み込み **/
if(fread(texture->imageData, 1, texture->imageSize, fTGA) != texture->imageSize)
{
puts("Error could not read image data");
fclose(fTGA);fTGA = NULL;
delete [] texture->imageData; texture->imageData =NULL;
exit(0);
}
}
/************ [RLE圧縮TGAの読み込み] *****************/
void LoadCompressedTGA(char *filename, FILE *fTGA, TGA_IMG *texture)
{
texture->RLE_flag = true;
SET_TGA_INFOMATION(texture,fTGA); //ヘッダ情報取得
/***** ここからデータ読み込み *******/
unsigned int pixelcount = texture->width * texture->height;//総ピクセル数
unsigned int currentpixel = 0;
unsigned int currentbyte = 0;
unsigned char* colorbuffer = new unsigned char[texture->color_num]; //1ピクセル分のメモリ確保
do
{
/** cunk headerを読む **/
unsigned char chunkheader = 0;
if(fread(&chunkheader, sizeof(unsigned char), 1, fTGA) == 0)
{
puts("wrong chunk");
fclose(fTGA);fTGA = NULL;
delete [] colorbuffer; colorbuffer = NULL;
delete [] texture->imageData; texture->imageData =NULL;
exit(0);
}
if(chunkheader < 128) //生データの場合
{
short counter;
chunkheader++;
for(counter = 0; counter < chunkheader; counter++) //(chunkheader)個分の生データを読む
{
if(fread(colorbuffer, 1, texture->color_num, fTGA) != texture->color_num)
{
puts("Error could not read image data");
fclose(fTGA);fTGA = NULL;
delete [] colorbuffer; colorbuffer = NULL;
delete [] texture->imageData; texture->imageData =NULL;
exit(0);
}
texture->imageData[currentbyte] = colorbuffer[2]; //red
texture->imageData[currentbyte + 1] = colorbuffer[1]; //green
texture->imageData[currentbyte + 2] = colorbuffer[0]; //blue
if(texture->color_num == 4)
{
texture->imageData[currentbyte + 3] = colorbuffer[3]; //alpha
}
currentbyte += texture->color_num;
currentpixel++;
if(currentpixel > pixelcount) //総ピクセル数より多く読みこんだらエラー
{
puts("Error too many pixels read");
fclose(fTGA);fTGA = NULL;
delete [] colorbuffer; colorbuffer = NULL;
delete [] texture->imageData; texture->imageData =NULL;
exit(0);
}
}
}else /******** [以降は、RLE圧縮データ部分] ***********/
{
short counter;
chunkheader -= 127;
if(fread(colorbuffer, 1, texture->color_num, fTGA) != texture->color_num)
{
printf("Error could not read from file");
fclose(fTGA);fTGA = NULL;
delete [] colorbuffer; colorbuffer = NULL;
delete [] texture->imageData; texture->imageData =NULL;
exit(0);
}
for(counter = 0; counter < chunkheader; counter++)
{
texture->imageData[currentbyte ] = colorbuffer[2];
texture->imageData[currentbyte + 1 ] = colorbuffer[1];
texture->imageData[currentbyte + 2 ] = colorbuffer[0];
if(texture->color_num == 4)
{
texture->imageData[currentbyte + 3] = colorbuffer[3];
}
currentbyte += texture->color_num;
currentpixel++;
if(currentpixel > pixelcount)
{
puts("Error too many pixels read");
fclose(fTGA);fTGA = NULL;
delete [] colorbuffer; colorbuffer = NULL;
delete [] texture->imageData; texture->imageData =NULL;
exit(0);
}
}//圧縮forループ終わり
}//未圧縮 or RLE圧縮 のif文の分岐終わり
}while(currentpixel < pixelcount); //全部のピクセルを回るまでループする
delete [] colorbuffer;colorbuffer = NULL;
}
/********** [ヘッダ情報を取得] **********************/
void SET_TGA_INFOMATION(TGA_IMG *texture,FILE *fTGA)
{
unsigned char tmp_headear[6];
if(fread(tmp_headear, sizeof(tmp_headear), 1, fTGA) == 0)//次の6バイトを読む
{
puts("can't read next header");
exit(0);
}
texture->width = tmp_headear[1] * 256 + tmp_headear[0];//幅
texture->height = tmp_headear[3] * 256 + tmp_headear[2];//高さ
texture->bpp = tmp_headear[4]; //24 or 32 bit
/** エラーチェック **/
if*1
{
puts("Wrong Data");
fclose(fTGA);fTGA = NULL;
exit(0);
}
/** 画像データ用のメモリ確保 **/
texture->color_num = (texture->bpp / 8);//色数(3 or 4)
texture->imageSize = (texture->color_num * texture->width * texture->height);
texture->imageData = new unsigned char[texture->imageSize];
if(texture->imageData == NULL)
{
puts("sorry can't get memory");
fclose(fTGA);fTGA = NULL;
delete [] texture->imageData; texture->imageData =NULL;
exit(0);
}
}
#include <cstdio>
#include <cstdlib>
#include <cv.h>
#include <highgui.h>
using namespace std;
/*** [データ構造] ***/
typedef struct
{
unsigned char* imageData;
unsigned int bpp;
unsigned int width;
unsigned int height;
bool RLE_flag;
unsigned int imageSize;
unsigned int color_num;
}TGA_IMG;
char *tgafilename ="image.tga";
/************* [プロトタイプ宣言] *******************/
void LoadTGA(char *filename, TGA_IMG *texture);
void LoadUncompressedTGA(char *filename, FILE *fTGA, TGA_IMG *texture);
void LoadCompressedTGA(char *filename, FILE *fTGA, TGA_IMG *texture);
void SET_TGA_INFOMATION(TGA_IMG *texture,FILE *fTGA);
/**************** [メイン関数] *********************/
int main(int argc, char**argv)
{
TGA_IMG *tga_img;
tga_img = new TGA_IMG();
LoadTGA(tgafilename,tga_img);
IplImage *imgA;
CvSize window_size;
window_size.width = tga_img->width;
window_size.height= tga_img->height;
imgA = cvCreateImage(window_size,IPL_DEPTH_8U,3);
memcpy(imgA->imageData,tga_img->imageData,tga_img->width*tga_img->height*3);
if(tga_img->RLE_flag == true)
{
cvCvtColor(imgA, imgA, CV_RGB2BGR);
}
cvFlip(imgA,NULL,0);
delete [] tga_img->imageData;tga_img->imageData=NULL;
delete tga_img;tga_img=NULL;
cvNamedWindow("load tga image",CV_WINDOW_AUTOSIZE);
cvShowImage("load tga image",imgA);
cvWaitKey(0);
cvReleaseImage( & imgA);
cvDestroyAllWindows();
return 0;
}
/*************** ここから各種関数 ********************/
void LoadTGA(char *filename, TGA_IMG *texture)
{
FILE *fTGA;
fTGA = fopen(filename,"rb");
if(fTGA ==NULL)
{
puts("can't open file");
exit(0);
}
/** 最初の12バイトを読み込む **/
unsigned char tgaheader[12];
if(fread(&tgaheader, sizeof(tgaheader), 1, fTGA) == 0)
{
puts("can't read header");
exit(0);
}
unsigned char uTGAcompare[12] = {0,0, 2,0,0,0,0,0,0,0,0,0};
unsigned char cTGAcompare[12] = {0,0,10,0,0,0,0,0,0,0,0,0};
/** 圧縮か未圧縮かで場合分け **/
if(memcmp(uTGAcompare, &tgaheader, sizeof(tgaheader)) == 0)
{
puts("this file is uncompressed");
LoadUncompressedTGA(filename, fTGA,texture);
}
else if(memcmp(cTGAcompare, &tgaheader, sizeof(tgaheader)) == 0)
{
puts("this file is compressed");
LoadCompressedTGA(filename, fTGA,texture);
}
else
{
puts("wrong!");
}
fclose(fTGA);fTGA=NULL;
}
/**************** [未圧縮TGAの読み込み] *****************/
void LoadUncompressedTGA(char *filename, FILE *fTGA, TGA_IMG *texture)
{
texture->RLE_flag = false;
SET_TGA_INFOMATION(texture,fTGA); //ヘッダ情報取得
/** データ読み込み **/
if(fread(texture->imageData, 1, texture->imageSize, fTGA) != texture->imageSize)
{
puts("Error could not read image data");
fclose(fTGA);fTGA = NULL;
delete [] texture->imageData; texture->imageData =NULL;
exit(0);
}
}
/************ [RLE圧縮TGAの読み込み] *****************/
void LoadCompressedTGA(char *filename, FILE *fTGA, TGA_IMG *texture)
{
texture->RLE_flag = true;
SET_TGA_INFOMATION(texture,fTGA); //ヘッダ情報取得
/***** ここからデータ読み込み *******/
unsigned int pixelcount = texture->width * texture->height;//総ピクセル数
unsigned int currentpixel = 0;
unsigned int currentbyte = 0;
unsigned char* colorbuffer = new unsigned char[texture->color_num]; //1ピクセル分のメモリ確保
do
{
/** cunk headerを読む **/
unsigned char chunkheader = 0;
if(fread(&chunkheader, sizeof(unsigned char), 1, fTGA) == 0)
{
puts("wrong chunk");
fclose(fTGA);fTGA = NULL;
delete [] colorbuffer; colorbuffer = NULL;
delete [] texture->imageData; texture->imageData =NULL;
exit(0);
}
if(chunkheader < 128) //生データの場合
{
short counter;
chunkheader++;
for(counter = 0; counter < chunkheader; counter++) //(chunkheader)個分の生データを読む
{
if(fread(colorbuffer, 1, texture->color_num, fTGA) != texture->color_num)
{
puts("Error could not read image data");
fclose(fTGA);fTGA = NULL;
delete [] colorbuffer; colorbuffer = NULL;
delete [] texture->imageData; texture->imageData =NULL;
exit(0);
}
texture->imageData[currentbyte] = colorbuffer[2]; //red
texture->imageData[currentbyte + 1] = colorbuffer[1]; //green
texture->imageData[currentbyte + 2] = colorbuffer[0]; //blue
if(texture->color_num == 4)
{
texture->imageData[currentbyte + 3] = colorbuffer[3]; //alpha
}
currentbyte += texture->color_num;
currentpixel++;
if(currentpixel > pixelcount) //総ピクセル数より多く読みこんだらエラー
{
puts("Error too many pixels read");
fclose(fTGA);fTGA = NULL;
delete [] colorbuffer; colorbuffer = NULL;
delete [] texture->imageData; texture->imageData =NULL;
exit(0);
}
}
}else /******** [以降は、RLE圧縮データ部分] ***********/
{
short counter;
chunkheader -= 127;
if(fread(colorbuffer, 1, texture->color_num, fTGA) != texture->color_num)
{
printf("Error could not read from file");
fclose(fTGA);fTGA = NULL;
delete [] colorbuffer; colorbuffer = NULL;
delete [] texture->imageData; texture->imageData =NULL;
exit(0);
}
for(counter = 0; counter < chunkheader; counter++)
{
texture->imageData[currentbyte ] = colorbuffer[2];
texture->imageData[currentbyte + 1 ] = colorbuffer[1];
texture->imageData[currentbyte + 2 ] = colorbuffer[0];
if(texture->color_num == 4)
{
texture->imageData[currentbyte + 3] = colorbuffer[3];
}
currentbyte += texture->color_num;
currentpixel++;
if(currentpixel > pixelcount)
{
puts("Error too many pixels read");
fclose(fTGA);fTGA = NULL;
delete [] colorbuffer; colorbuffer = NULL;
delete [] texture->imageData; texture->imageData =NULL;
exit(0);
}
}//圧縮forループ終わり
}//未圧縮 or RLE圧縮 のif文の分岐終わり
}while(currentpixel < pixelcount); //全部のピクセルを回るまでループする
delete [] colorbuffer;colorbuffer = NULL;
}
/********** [ヘッダ情報を取得] **********************/
void SET_TGA_INFOMATION(TGA_IMG *texture,FILE *fTGA)
{
unsigned char tmp_headear[6];
if(fread(tmp_headear, sizeof(tmp_headear), 1, fTGA) == 0)//次の6バイトを読む
{
puts("can't read next header");
exit(0);
}
texture->width = tmp_headear[1] * 256 + tmp_headear[0];//幅
texture->height = tmp_headear[3] * 256 + tmp_headear[2];//高さ
texture->bpp = tmp_headear[4]; //24 or 32 bit
/** エラーチェック **/
if*1
{
puts("Wrong Data");
fclose(fTGA);fTGA = NULL;
exit(0);
}
/** 画像データ用のメモリ確保 **/
texture->color_num = (texture->bpp / 8);//色数(3 or 4)
texture->imageSize = (texture->color_num * texture->width * texture->height);
texture->imageData = new unsigned char[texture->imageSize];
if(texture->imageData == NULL)
{
puts("sorry can't get memory");
fclose(fTGA);fTGA = NULL;
delete [] texture->imageData; texture->imageData =NULL;
exit(0);
}
}