开发环境:VS2015+Qt5.8,以官方所给asynchronousopencvrecorder的demo为例。
获取相机
VmbErrorType err = m_ApiController.StartUp();
初始化某个相机参数,m_cameras为列表容器,nRow为int,可以手动设置。
err = m_ApiController.StartContinuousImageAcquisition(m_cameras[nRow]);
以上函数关键代码,设置FPS,曝光时间,ROI区域等,更多的可以通过相机软件保存相机参数,到参数文件里面找相应的特征名。
m_FPS = 100.0;
FeaturePtr pFeatureFPS ;
res = SP_ACCESS( m_pCamera )->GetFeatureByName("AcquisitionFrameRateAbs", pFeatureFPS);
if( VmbErrorSuccess != res)
{
res = SP_ACCESS( m_pCamera )->GetFeatureByName("AcquisitionFrameRate", pFeatureFPS);
}
if( VmbErrorSuccess == res )
{
res = SP_ACCESS(pFeatureFPS)->GetValue( m_FPS );
}
m_exposure = 2200.0;
FeaturePtr pFeature_exposure;
res = SP_ACCESS(m_pCamera)->GetFeatureByName("Exposure Time", pFeature_exposure);
if (VmbErrorSuccess != res)
{
res = SP_ACCESS(m_pCamera)->GetFeatureByName("ExposureTimeAbs", pFeature_exposure);
}
if (VmbErrorSuccess == res)
{
res = SP_ACCESS(pFeature_exposure)->SetValue(m_exposure);
}
FeaturePtr offset_x;
res = SP_ACCESS(m_pCamera)->GetFeatureByName("OffsetX", offset_x);
if (VmbErrorSuccess == res)
{
res = SP_ACCESS(offset_x)->SetValue(m_offset_x);
}
FeaturePtr offset_y;
res = SP_ACCESS(m_pCamera)->GetFeatureByName("OffsetY", offset_y);
if (VmbErrorSuccess == res)
{
res = SP_ACCESS(offset_y)->SetValue(m_offset_y);
}
图片大小可在ApiController.h里面设置
VmbInt64_t m_nWidth = 360;
VmbInt64_t m_nHeight = 180;
python用于inceptionv 3分类,c++用于产生图片。为了节约开发时间,c++将图片写入固定目录,然后python读取固定目录检测,为了两边线程的安全,用了比较蠢的办法:读取txt!两边同时判断。隐掉的部分可用于格式化批量保存图片。
void AsynchronousOpenCVRecorder::OnFrameReady(int status)
{
if (true == m_bIsStreaming)
{
// Pick up frame
FramePtr pFrame = m_ApiController.GetFrame();
if (SP_ISNULL(pFrame))
{
Log("frame pointer is NULL, late frame ready message");
return;
}
// See if it is not corrupt
if (VmbFrameStatusComplete == status)
{
if (!m_pVideoRecorder.isNull())
{
m_pVideoRecorder->enqueueFrame(*pFrame);
}
VmbUchar_t *pBuffer;
VmbErrorType err = SP_ACCESS(pFrame)->GetImage(pBuffer);
if (VmbErrorSuccess == err)
{
VmbUint32_t nSize;
err = SP_ACCESS(pFrame)->GetImageSize(nSize);
if (VmbErrorSuccess == err)
{
VmbPixelFormatType ePixelFormat = m_ApiController.GetPixelFormat();
if (!m_Image.isNull())
{
QFile f1("test.txt");
f1.open(QIODevice::Text | QIODevice::ReadOnly);
if (f1.readLine() == QByteArray("0"))
{
f1.close();
CopyToImage(pBuffer, ePixelFormat, m_Image);
cv::Mat mat;
mat = cv::Mat(m_Image.height(), m_Image.width(), CV_8UC3, (void*)m_Image.constBits(), m_Image.bytesPerLine());
/*char image[128];
n++;
sprintf(image, "F:/new/new_wet2_%d%s",n, ".jpg");
bool mark = cv::imwrite(image ,mat);*/
bool mark=cv::imwrite("C://Users//惠普//Desktop//磁瓦检测项目1//class_transfer_learning//test.jpg", mat);
if (mark)
{
const QSize s = ui.m_LabelStream->size();
ui.m_LabelStream->setPixmap(QPixmap::fromImage(m_Image).scaled(s, Qt::KeepAspectRatio));
QFile f2("test2.txt");
f2.open(QIODevice::Text | QIODevice::ReadOnly);
if (f2.readLine() == QByteArray("0"))
{
ui.label_4->setText(QString::fromLocal8Bit("不正常"));
}
else
{
ui.label_4->setText(QString::fromLocal8Bit("正常"));
}
//Sleep(100);
QFile f("test.txt");
QString b = "1";
f.open(QIODevice::Text | QIODevice::ReadWrite);
f.write(b.toLatin1(), b.length());
f.close();
}
}
}
}
}
}
else
{
// If we receive an incomplete image we do nothing but logging
Log("Failure in receiving image", VmbErrorOther);
}
// And queue it to continue streaming
m_ApiController.QueueFrame(pFrame);
}
}
开启视频录制线程:
m_pVideoRecorder = OpenCVRecorderPtr(new OpenCVRecorder("AsynchronousOpenCVRecorder.avi", FPS, Width, Height));
m_pVideoRecorder->start();
线程核心代码:
while( ! m_StopThread )
{
FrameStorePtr tmp;
{
// two class events unlock the queue
// first if a frame arrives enqueueFrame wakes the condition
// second if the thread is stopped we are woken up
// the while loop is necessary because a condition can be woken up by the system
QMutexLocker local_lock( &m_ClassLock );
while(! m_StopThread && m_FrameQueue.empty() )
{
m_FramesAvailable.wait( local_lock.mutex() );
}
if( ! m_StopThread)
{
tmp = m_FrameQueue.front();
m_FrameQueue.pop_front();
}
}// scope for the lock, from now one we don't need the class lock
if( ! m_StopThread)
{
convertImage( *tmp );
m_VideoWriter << m_ConvertImage;
}
}
在Qt Designer里面
这样虽然UI有图标了,但是生成exe却没有。
新建一个.rc文件,写入
IDI_ICON1 ICON DISCARDABLE "AVT.ico"
并把.rc和.ico添加到工程里面即可
找到VS的输出路径,添加相应的dll文件,双击exe文件确认是否可以运行,再发送到桌面快捷方式,这个时候进入 C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp 路径(win10),把快捷方式拖到里面就可以了。