AVT Mako/Manta面阵相机开发小结
开发环境: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 frameFramePtr pFrame = m_ApiController.GetFrame();if (SP_ISNULL(pFrame)){Log("frame pointer is NULL, late frame ready message");return;}// See if it is not corruptif (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 loggingLog("Failure in receiving image", VmbErrorOther);}// And queue it to continue streamingm_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 systemQMutexLocker 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 lockif( ! m_StopThread){convertImage( *tmp );m_VideoWriter << m_ConvertImage;}}
VS+QT exe图标问题:
在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),把快捷方式拖到里面就可以了。
AVT Mako/Manta面阵相机开发小结
开发环境: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 frameFramePtr pFrame = m_ApiController.GetFrame();if (SP_ISNULL(pFrame)){Log("frame pointer is NULL, late frame ready message");return;}// See if it is not corruptif (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 loggingLog("Failure in receiving image", VmbErrorOther);}// And queue it to continue streamingm_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 systemQMutexLocker 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 lockif( ! m_StopThread){convertImage( *tmp );m_VideoWriter << m_ConvertImage;}}
VS+QT exe图标问题:
在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),把快捷方式拖到里面就可以了。