【发布时间】:2018-07-09 14:15:46
【问题描述】:
我面临以下问题:
我使用 C++ 程序来控制连接到我的 PC 的科学相机。它以尽可能快的快门时间拍摄照片(每张图像约 1 秒)。
在当前阶段,该程序会在每张照片制作完成后立即将其保存到硬盘中。看来,I/O 访问需要花费大量时间(每次保存大约 1/2 秒),这大大降低了图像速率。
我一直在考虑先存储许多图像(例如,存储在一个数组中),然后将它们全部保存在一批中。
那行得通吗?有什么好的选择吗?遇到这样的问题怎么办?
制作视频而不是图像不是一种选择。
非常感谢
编辑:这是我正在使用的代码:
// capture loop: add up 'preint' images read out with 12 bit adc resolution
// and save them as 16 bit image
// read out current shutter register
// read the 32-bit hex value into the unsigned long member of the above defined union
cam.ReadRegister( 0x918, &curShutter.ulValue );
fCurShutter = curShutter.fValue;
cout << "Grab # " << ip.cnt << "; Serv: " << ip.servopos << "; Expt: " << ip.exptime << "; T: " << ip.temp << "; prog " ;
//inner capture loop
for ( int imageCnt=0; imageCnt < ip.preint; imageCnt++ )
{
error = cam.RetrieveBuffer( &monoImage );
if (error != PGRERROR_OK){PrintError( error ); continue;}
cout << "." ;
//convert to cv::Mat image
unsigned int rowBytes = (double)monoImage.GetReceivedDataSize()/(double)monoImage.GetRows();
cv_image = cv::Mat(monoImage.GetRows(), monoImage.GetCols(), CV_16UC1, monoImage.GetData(),rowBytes);
cv_sum_image = cv_sum_image + cv_image/ip.preint;
cv::imshow("image", cv_sum_image);
cv::waitKey(1);
}
//t=GetTickCount() - t;
unsigned int shutterus = fCurShutter*1000000;
{
//create filename and save co-added image
ostringstream filename;
filename << ip.mode <<"_"<< ip.cdt << "_" << setfill('0') << setw(5) << ip.cnt << "_" << ip.servopos << "_" << setfill('0') << setw(6) << shutterus << "_" << ip.preint << "_" << ip.temp << "_" << ip.pres <<".pgm";
//cv::string ss = filename.str();
string ss = filename.str();
cv::imwrite(ss,cv_sum_image);
}
// Stop capturing images
error = cam.StopCapture();
if (error != PGRERROR_OK){PrintError( error ); return -1;}
// Disconnect the camera
error = cam.Disconnect();
if (error != PGRERROR_OK){ PrintError( error ); return -1;}
return 0;
}
也许问题出在 opencv 例程中?
【问题讨论】:
-
图片有多大?是否可以选择更好的存储介质(例如 SSD、存储卡)?
-
您使用的是什么操作系统?默认情况下,Linux 将异步“写入”磁盘。 write 调用会将数据复制到缓冲区并很快将控制权返回给您的程序,然后内核将在稍后的某个时间将数据物理写入磁盘。
-
我会考虑在每个文件中放入多个图像——这可能有助于减少磁头跳动;还有 - 您需要记录多少张图像?如果你可以把它全部放在内存中,那么就这样做,然后在最后转储到磁盘。
-
一般来说,您希望查看数据速率(字节/秒)、硬件设置以及访问磁盘的其他内容。我很惊讶你报告的速度有多慢。我的猜测是,您可能有一个缓慢的 HDD 和/或其他程序大量访问磁盘和/或一个缓慢的 CPU 和/或 非常 大图像,可能在 Windows 上。修复将取决于您的情况是这些因素的哪种组合。
-
@JMAA Linux 将异步“写入”磁盘 Windows 也是如此。和 macOS。还有……