画像処理関数
RAWで処理する関数を作成しました。
void InitImage(unsigned short *dst, int width, int height, unsigned short val);
void SLImage(unsigned short *dst, unsigned short *src, int width, int height, int num);
void SDImage(unsigned short *dst, unsigned short *src, int width, int height, int num);
void AvrImage(unsigned short *dst, unsigned short *src, int width, int height, int num);
void SubImage(unsigned short *dst, unsigned short *src, int width, int height, int num);
void DifImage(unsigned short *dst, unsigned short *src1, unsigned short *src2, int width, int height, int num);
void AbsImage(unsigned short *dst, unsigned short *src, int width, int height, int num);
void CopyImage(unsigned short *dst, unsigned short *src, int width, int height, int num);
float BinzImage(unsigned short *dst, unsigned short threshold, int width, int height);
float CountImage(unsigned short *dst, unsigned short threshold, int width, int height);
void SDeviImage(unsigned short *dst, unsigned short threshold, int width, int height, double *ax, double *ay, double *sx, double *sy);
void MaxMinImage(unsigned short *dst, unsigned short threshold, int width, int height, int *minx, int *miny, int *maxx, int *maxy);
void NRImage(unsigned short *dst, unsigned short threshold, int width, int height);
void WBImageRG(unsigned short *src, int width, int height);
バッチ版ソース
int readSer(char *path, float lthresh, float ratio){
FILE *fpSer;
serHeader SerHeader;
char tmpc[41];
printf("%s\n",path);
fpSer = fopen64(path, "rb");
int r = fread(&SerHeader.FileID, 1, sizeof(SerHeader.FileID), fpSer);
strncpy(tmpc, SerHeader.FileID, 14);
tmpc[14]='\0';
r = fread(&SerHeader.LuID, 1, sizeof(SerHeader.LuID), fpSer);
r = fread(&SerHeader.ColorID, 1, sizeof(SerHeader.ColorID), fpSer);
r = fread(&SerHeader.LittleEndian, 1, sizeof(SerHeader.LittleEndian), fpSer);
r = fread(&SerHeader.ImageWidth, 1, sizeof(SEEK_CUR), fpSer);
r = fread(&SerHeader.ImageHeight, 1, sizeof(SerHeader.ImageHeight), fpSer);
r = fread(&SerHeader.PixelDepthPerPlane, 1, sizeof(SerHeader.PixelDepthPerPlane), fpSer);
r = fread(&SerHeader.FrameCount, 1, sizeof(SerHeader.FrameCount), fpSer);
r = fread(&SerHeader.Observer, 1, sizeof(SerHeader.Observer), fpSer);
strncpy(tmpc, SerHeader.Observer, 40);
tmpc[40]='\0';
r = fread(&SerHeader.Instrument, 1, sizeof(SerHeader.Instrument), fpSer);
strncpy(tmpc, SerHeader.Instrument, 40);
tmpc[40]='\0';
r = fread(&SerHeader.Telescope, 1, sizeof(SerHeader.Telescope), fpSer);
strncpy(tmpc, SerHeader.Telescope, 40);
tmpc[40]='\0';//
int year, month, day, hour, minute, second, microsec;
r = fread(&SerHeader.DateTime, 1, sizeof(SerHeader.DateTime), fpSer);
timestamp2date(SerHeader.DateTime, &year, &month, &day, &hour, &minute, &second, µsec);
r = fread(&SerHeader.DateTime_UTC, 1, sizeof(SerHeader.DateTime_UTC), fpSer);
timestamp2date(SerHeader.DateTime_UTC, &year, &month, &day, &hour, &minute, &second, µsec);
unsigned long TrailerDate;
unsigned long *TrailerDateP = (unsigned long *)malloc(SerHeader.FrameCount * sizeof(TrailerDate));
fseek(fpSer, -1*SerHeader.FrameCount * sizeof(TrailerDate), SEEK_END);
for(int i = 0; i < SerHeader.FrameCount; i++){
r = fread(&TrailerDate, 1, sizeof(TrailerDate), fpSer);
if(r < 1){
printf("trailer read error\n");
free(TrailerDateP);
return(1);
}
TrailerDateP[i] = TrailerDate;
timestamp2date(TrailerDate, &year, &month, &day, &hour, &minute, &second, µsec);
}
fseek(fpSer, 178, SEEK_SET);
int RawSize = SerHeader.ImageWidth * SerHeader.ImageHeight * SerHeader.PixelDepthPerPlane / 8;
cv::Mat rgb8BitMat(SerHeader.ImageHeight, SerHeader.ImageWidth, CV_8UC3); // RGB用バッファを用意
cv::Mat rgb8BitMat2(SerHeader.ImageHeight/2, SerHeader.ImageWidth/2, CV_8UC3); // RGB用バッファを用意
int oc = -1;
for(int i=0; i<SerHeader.FrameCount; i++){
Temp = OldImage;
OldImage = NewImage;
NewImage = Temp;
int r = fread(NewImage, sizeof(char), RawSize, fpSer);
if(DarkImage != NULL)
SubImage(NewImage, DarkImage, SerHeader.ImageWidth, SerHeader.ImageHeight, 0);
WBImageRG((unsigned short *)NewImage, SerHeader.ImageWidth, SerHeader.ImageWidth);
if(mask_r.data != NULL)
bmask(mask_r, (unsigned short *)NewImage);
if(i == 0)//
continue;
if(r < RawSize){
printf("image read error\n");
break;
}
DifImage(DffImage, NewImage, OldImage, SerHeader.ImageWidth, SerHeader.ImageHeight, 0);
NRImage(DffImage, 0x580, , SerHeader.ImageHeight);
if(mask_d.data != NULL)
bmask(mask_d, DffImage);
float lrate = BinzImage(DffImage, 0x580, SerHeader.ImageWidth, SerHeader.ImageHeight) * 100;
if(lrate < 0.03 && lrate > lthresh){
double ax, ay, sx, sy;
SDeviImage(DffImage, 0x580, SerHeader.ImageWidth, SerHeader.ImageHeight, &ax, &ay, &sx, &sy);
if(sx/(double)SerHeader.ImageWidth < 0.01 || sy/(double)SerHeader.ImageHeight < 0.01){
fc++;
if(i != oc + 1){
mc++;
printf("Meteor No. %d, frame No. %d\n", mc, i);
}
int minx, miny, maxx, maxy;
MaxMinImage(DffImage, 0x580, SerHeader.ImageWidth, SerHeader.ImageHeight, &minx, &miny, &maxx, &maxy);
oc = i;
cv::Mat OutImage(cv::Size(SerHeader.ImageWidth * 2, SerHeader.ImageHeight), CV_8UC3); // 合成後のイメージ作成
cv::Mat imageLeft(OutImage, cv::Rect( 0, 0, rgb8BitMat.cols, rgb8BitMat.rows)); // コピーする領域左側
cv::Mat imageRight(OutImage, cv::Rect(SerHeader.ImageWidth, 0, rgb8BitMat.cols, rgb8BitMat.rows)); // コピーする領域右側
cv::Mat bayer16BitMat(SerHeader.ImageHeight, SerHeader.ImageWidth, CV_16UC1, NewImage); // 16bit用バッファを用意して取り込み
cv::Mat bayer8BitMat = bayer16BitMat.clone(); // 8bit用バッファを用意
bayer8BitMat.convertTo(bayer8BitMat, CV_8UC1, 0.0625*ratio); // 8bitに変換
cv::cvtColor(bayer8BitMat, rgb8BitMat, cv::COLOR_BayerRG2RGB); // デベイヤー
rgb8BitMat.copyTo(imageRight); // 右側にコピーして表示させる
cv::rectangle(imageRight, cv::Point(ax-1, ay-1), cv::Point(ax+1, ay+1), CV_RGB(255,0,0), 2, 10, 0); // 赤の矩形
cv::rectangle(imageRight, cv::Point(ax-sx, ay-sy), cv::Point(ax+sx, ay+sy), CV_RGB(0,0,255), 2, 10, 0); // 緑の矩形
cv::rectangle(imageRight, cv::Point(minx, miny), cv::Point(maxx, maxy), CV_RGB(0,255,0), 2, 10, 0); // 緑の矩形
cv::Mat bayer16BitMat2(SerHeader.ImageHeight, SerHeader.ImageWidth, CV_16UC1, DffImage); // 16bit用バッファを用意して取り込み
bayer8BitMat = bayer16BitMat2.clone(); // 8bit用バッファを用意
bayer8BitMat.convertTo(bayer8BitMat, CV_8UC1, 0.0625*ratio); // 8bitに変換
cv::cvtColor(bayer8BitMat, rgb8BitMat, cv::COLOR_BayerRG2RGB); // デベイヤー
timestamp2date(TrailerDateP[i], &year, &month, &day, &hour, &minute, &second, µsec);
sprintf(str, "%4.4d %4.4d %4.4d:%2.4f%", fc, mc, i, lrate);
cv::putText(rgb8BitMat, str, cv::Point(20, 50),cv::FONT_HERSHEY_SIMPLEX, 1, CV_RGB(200,200,200), 1);
sprintf(str, "%4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d.%4.4dUTC", year, month, day, hour, minute, second, microsec);
cv::putText(rgb8BitMat, str, cv::Point(20, 100),cv::FONT_HERSHEY_SIMPLEX, 1, CV_RGB(200,200,200), 1);
sprintf(str, "ax:%04.0lf ay:%04.0lf sx:%04.0lf sy:%04.0lf", ax, ay, sx, sy);
cv::putText(rgb8BitMat, str, cv::Point(20, SerHeader.ImageHeight - 20),cv::FONT_HERSHEY_SIMPLEX, 1, CV_RGB(200,200,200), 1);
rgb8BitMat.copyTo(imageLeft); // 左側にコピーして表示させる
fprintf(fpLog,"%4.4d,%4.4d,%s,%4.4d,%4.4d-%2.2d-%2.2d,%2.2d:%2.2d:%2.2d.%4.4dUTC,%2.4f%\n"
, fc, mc, path, i, year, month, day, hour, minute, second, microsec, lrate);
writer << OutImage; // 画像 image を動画ファイルへ書き出す
cv::resize(OutImage, OutImage, cv::Size(), 0.5, 0.5); // 縮小
writer2 << OutImage; // 画像 image を動画ファイルへ書き出す
SLImage(StkImage, DffImage, SerHeader.ImageWidth, SerHeader.ImageHeight, 0);
}
}
}
free(TrailerDateP);
fclose(fpSer);
return 0;
}
リアルタイム版ソース
//-------------------------------------------------------------------
// 画像を読み込み,表示する
//-------------------------------------------------------------------
timeout_counter = 0;
frame_count = oc = 0;
st = GetTime();
zoom_setMouseCallback((char *)"se_cam", 1/(float)div);
while (1) {
if (ReadRAW(RawImage) == 0) {
if (++timeout_counter > TIMEOUT) {
fprintf(stderr, "sensorlaunch: time out.\n");
return 1;
}
usleep(500);
continue;
}
frame_count++;
timeout_counter = 0;
unsigned char *Temp = BinImage3;
BinImage3 = BinImage2;
BinImage2 = Temp;
CnvertImage(BinImage2, RawImage, RawSize, rawbit, raw8_flag);
if(mask_r.data != NULL)
bmask(mask_r, (unsigned short *)BinImage2);
if(mode == SERD_MODE){
DifImage((unsigned short *)DiffImage, (unsigned short *)BinImage2, (unsigned short *)BinImage3, width, height, 0);
NRImage((unsigned short *)DiffImage, bthresh >> (16-bpp), width, height);
if(mask_d.data != NULL)
bmask(mask_d, (unsigned short *)DiffImage);
BinzImage((unsigned short *)DiffImage, bthresh >> (16-bpp), width, height);
float lrate = CountImage((unsigned short *)DiffImage, bthresh >> (16-bpp), width, height) * 100;
if(lrate > 0.001){
double ax, ay, sx, sy;
SDeviImage((unsigned short *)DiffImage, bthresh >> (16-bpp), width, height, &ax, &ay, &sx, &sy);
if(sx/(double)width < 0.1 || sy/(double)height < 0.1){
printf("%5d:Diff Detect. sx:%04.0lf sy:%04.0lf\n", ++diffcount, sx, sy);
diff = ON;
if(frame_count != oc +1)
system("~/detect_voice.sh");
oc = frame_count;
}
}
// 差分表示用
cv::Mat bayerXBitMat2(height, width, depth, DiffImage); // Xbit用バッファを用意して取り込み
cv::Mat bayer8BitMat2 = bayerXBitMat2.clone(); // 8bit用バッファを用意
resize(bayer8BitMat2, bayer8BitMat2, cv::Size(), 1/(float)div, 1/(float)div); // 縮小
cv::imshow("ImageDiff", bayer8BitMat2); // ウィンドウに画像を表示する
// 差分積算表示用
if(diff == ON){
SLImage((unsigned short *)StkImage, (unsigned short *)DiffImage, width, height, 0);
cv::Mat bayer8BitMat3(height, width, CV_16UC1, StkImage); // 16bit用バッファを用意して取り込み
bayer8BitMat3.convertTo(bayer8BitMat3, CV_8UC1, 0.0625*2); // 8bitに変換
sprintf(str, "%d differences detected", diffcount);
cv::putText(bayer8BitMat3, str, cv::Point(20, 50),cv::FONT_HERSHEY_SIMPLEX, 1, CV_RGB(200,200,200), 1);
resize(bayer8BitMat3, bayer8BitMat3, cv::Size(), 1/(float)div, 1/(float)div); // 縮小
cv::imshow("ImageDiffStack", bayer8BitMat3); // ウィンドウに画像を表示する
}
}
// メインのRAW表示用
cv::Mat bayerXBitMat(height, width, depth, BinImage2); // Xbit用バッファを用意して取り込み
cv::Mat bayer8BitMat = bayerXBitMat.clone(); // 8bit用バッファを用意
if(!raw8_flag){
bayer8BitMat.convertTo(bayer8BitMat, CV_8UC1, 0.02*4); // 8bitに変換
}
cv::Mat rgb8BitMat(height, width, CV_8UC3); // 保存用RGBバッファを用意
cv::Mat dsp8BitMat(height, width, CV_8UC3); // 表示用RGBバッファを用意
cv::cvtColor(bayer8BitMat, rgb8BitMat, cv::COLOR_BayerRG2RGB); // デベイヤー
resize(rgb8BitMat, dsp8BitMat, cv::Size(), 1/(float)div, 1/(float)div); // 縮小
zoom_imshow(rgb8BitMat, dsp8BitMat, 2.0); // 拡大表示ウィンドウに画像を表示する
cv::imshow("se_cam", dsp8BitMat); // ウィンドウに画像を表示する
// キー入力の処理