Преглед изворни кода

新增大华相机拍照模块代码

niujiuru пре 2 месеци
родитељ
комит
6d3258f985
3 измењених фајлова са 112 додато и 3 уклоњено
  1. 74 2
      dh_takephoto/takephoto.c
  2. 1 1
      dh_takephoto/takephoto.h
  3. 37 0
      dh_takephoto/takephoto_test.c

+ 74 - 2
dh_takephoto/takephoto.c

@@ -62,7 +62,7 @@ static void OnFrameReceived(IMV_Frame *pFrame, void *pUser)             // 数
   {
     double curExpTime = 0.0;
     ret = IMV_GetDoubleFeatureValue(ctx->hCam, "ExposureTime", &curExpTime);
-    if(IMV_OK != ret) goto endp;
+    if(IMV_OK != ret) goto end_p;
 
     struct timespec now; clock_gettime(CLOCK_MONOTONIC, &now);
     long elapsed = (now.tv_sec - ctx->expTime0.tv_sec)*1000 + (now.tv_nsec-ctx->expTime0.tv_nsec)/(1000*1000); // 计算时间差, 单位: ms
@@ -82,7 +82,7 @@ static void OnFrameReceived(IMV_Frame *pFrame, void *pUser)             // 数
   ret = SavePhoto(ctx->hCam, pFrame, ctx->saveImgType, ctx->saveImgPath);
 
   // 4, 设置拍照完成
-endp:
+end_p:
   ctx->rCode = ret; sw_signal_give(ctx->hESig);
 }
 
@@ -183,8 +183,74 @@ findp:
   }
 
   // 4, 开始拍照, 等待完成后输出
+  ret = IMV_GetEnumFeatureSymbol(hCam, "ExposureAuto", &exposureMode);
+  if(IMV_OK != ret)
+  {
+    sw_log_error("[%s] 获取曝光模式时出错, errCode=%d!!", MODULE_NAME,  ret);
+    goto end_p;
+  }
+  if(xstrcasecmp(exposureMode.str, "Off") != 0) { ctx.isExposureAuto = true; clock_gettime(CLOCK_MONOTONIC, &ctx.expTime0); }
+  else ctx.isExposureAuto = false;
+
+  ctx.hCam = hCam;
+  ctx.saveImgType = imgType;
+  ctx.saveImgPath = saveImgPath;
+  ctx.hESig = sw_signal_create();
+  if(!ctx.hESig)
+  {
+    ret = -7;
+    sw_log_error("[%s] SIG信号量创建失败!!", MODULE_NAME);
+    goto end_p;
+  }
+  ctx.rCode = IMV_OK;
+
+  ret = IMV_AttachGrabbing(hCam, OnFrameReceived, (void *)&ctx);
+  if(IMV_OK != ret)
+  {
+    sw_log_error("[%s] 注册回调时发生错误, errCode=%d!!", MODULE_NAME,  ret);
+    goto end_p;
+  }
+
+  ret = IMV_StartGrabbing(hCam);
+  if(IMV_OK != ret)
+  {
+    sw_log_error("[%s] 相机取流时发生错误, errCode=%d!!", MODULE_NAME,  ret);
+    goto end_p;
+  }
+
+  HANDLE hThrd = NULL;
+  if(0 != xstrcasecmp(setTriggerMode, "On")) goto waitp;
+
+  hThrd = sw_thrd_create("PhotoProc", THREAD_DEFAULT_PRIORITY, THREAD_DEFAULT_STACK_SIZE, FrameSoftTrigger, (unsigned long)&ctx, 0);
+  if(!hThrd)
+  {
+    ret = -8;
+    sw_signal_destroy(ctx.hESig);
+    sw_log_error("[%s] 触发线程-创建失败!!", MODULE_NAME);
+    goto end_p;
+  }
+  sw_thrd_resume(hThrd);
+
+waitp:
+  ret = sw_signal_wait(ctx.hESig, timeout*1000); // 阻塞等待拍照任务结束或超时
+  if(0 == ret) ret = ctx.rCode;
+  else
+  {
+    ret = -9;
+    sw_log_error("[%s] 拍照过程-等待超时!!", MODULE_NAME);
+  }
+
+  if(hThrd) sw_thrd_destroy(hThrd, WAITTHRD_SAFEEXIT_TIMEOUT);
+  sw_signal_destroy(ctx.hESig);
 
   // 5, 成功拍照, 输出相机的信息
+  if(IMV_OK == ret)
+  {
+    double curExpTime = 0.0;
+    IMV_GetDoubleFeatureValue(hCam, "ExposureTime", &curExpTime);
+    imgMark.imgExposureTime = curExpTime;
+    if(pImgMark) memcpy(pImgMark, &imgMark, sizeof(DHImgMark));
+  }
 
   // 6, 任务结束, 释放相关的资源
 end_p:
@@ -202,6 +268,12 @@ end_p:
   return ret;
 }
 
+// 保存照片
+static int SavePhoto(HANDLE hCam, IMV_Frame *pFrame, DHImgType imgType, const char *imgFile)
+{
+  return IMV_OK; // todo: 实现保存照片功能
+}
+
 // 获取系统当前USBFS内存大小(MB), 成功返回: >=0, 失败返回: <0值
 int DH_GetSysUsbfsMemCurrentSize()
 {

+ 1 - 1
dh_takephoto/takephoto.h

@@ -15,7 +15,7 @@ typedef struct
 {
   char camModelName[MAX_LINE_CHARS]; // 相机型号名
   char camSerialNum[MAX_LINE_CHARS]; // 相机序列号
-  float imgExposureTime; // 拍照曝光时间, 单位: us
+  double imgExposureTime; //拍照曝光时间, 单位: us
 } DHImgMark;
 
 // 图像类型

+ 37 - 0
dh_takephoto/takephoto_test.c

@@ -0,0 +1,37 @@
+// +build ignore
+
+#include "takephoto.h"
+
+// 主函数入口, 测试拍照
+int main(int argc,char *argv[])
+{
+  int ret = 0; unsigned long stime, wtime, etime; DHImgMark imgMark = { 0 };
+  char filename[MAX_PATH_CHARS] = { 0 }; int timeout = 5*60;
+
+  if(DH_GetSysUsbfsMemCurrentSize() < 200) ret = DH_SetSysUsbfsMemSize(200);
+  if(0 != ret)
+  {
+    sw_log_error("Failed to set system usbfs's memory size, ret=%d!!", ret);
+    return ret;
+  }
+
+  sw_log_info("Get DH camera count: %d", DH_GetCameraCount());
+
+  sw_log_info("Photo taking...");
+  for(int i = 0; i < 9; i++)
+  {
+    sprintf(filename, "test%d.jpg", i+1);
+
+    xgettickcount(&stime);
+    ret = DH_TakePhoto(IMG_TYPE_JPG, filename, timeout, &imgMark);
+    xgettickcount(&etime);
+
+    wtime = etime - stime;
+    if(0 == ret) sw_log_info("+++ Take a photo: \"%s\", time: %lums, exposure time: %fus, camera sn: %s, camera model: %s +++", filename, wtime, imgMark.imgExposureTime, imgMark.camSerialNum, imgMark.camModelName);
+    else sw_log_error("+++ Failed to take a photo, ret=%d, time: %lums!! +++", ret, wtime);
+
+    sw_thrd_delay(1000); // 轮询拍照测试时, 给系统预留一定的相机释放时间
+  }
+
+	return 0;
+}