Sfoglia il codice sorgente

优化海康相机封装模块代码

niujiuru 1 giorno fa
parent
commit
e38a29542e
3 ha cambiato i file con 33 aggiunte e 13 eliminazioni
  1. 29 13
      hk_takephoto/takephoto.c
  2. 2 0
      hk_takephoto/takephoto_test.c
  3. 2 0
      tests/hk_takephoto/main.go

+ 29 - 13
hk_takephoto/takephoto.c

@@ -26,9 +26,11 @@ static int SavePhoto(HANDLE hCam, MV_FRAME_OUT *pFrame, EImgType imgType, const
 // 拍照回调
 typedef struct
 {
-  HANDLE      hCam;
-  EImgType    saveImgType;
-  const char *saveImgPath;
+  HANDLE      hCam;           // 打开相机的句柄
+  uint32_t    camType;        // 相机类型:U、网
+  char manuName[MAX_LINE_CHARS]; //制造厂商名称
+  EImgType    saveImgType;    // 保存图像的类型
+  const char *saveImgPath;    // 保存图像的路径
   bool        isExposureAuto; // 自动曝光:是/否
   struct timespec expTime0;   // 曝光开始的时间
   float       lastExpTime;    // 上次的曝光时长(us)
@@ -37,6 +39,19 @@ typedef struct
   int         rCode;          // 任务结束返回值
 } PthotoProcCtx;
 
+// 网口相机
+// 支持的第三方厂商列表(用海康的SDK操作相机并拍照)
+static const char * const gige_3rd_manu_names[] = {"Huaray Technology", "Machine Vision"};
+static bool gige_3rd_manu_supported(const char *name)
+{
+  if(0 == GIGE_CAMERA_ANY_VENDOR) return false;
+  for(int i = 0; i < sizeof(gige_3rd_manu_names)/sizeof(gige_3rd_manu_names[0]); i++)
+  {
+    if(xstrcasecmp(name, gige_3rd_manu_names[i]) == 0) return true;
+  }
+  return false;
+}
+
 static int PhotoProc(unsigned long wParam, unsigned long lParam) // 线程回调函数,执行一次拍照任务
 {
   PthotoProcCtx *ctx = (PthotoProcCtx *)wParam; MV_FRAME_OUT frame = { 0 }; int ret;
@@ -44,6 +59,7 @@ static int PhotoProc(unsigned long wParam, unsigned long lParam) // 线程回调
   // 1, 触发一次拍照
 getp:
   ret = (setTriggerMode == MV_TRIGGER_MODE_ON) ? MV_CC_SetCommandValue(ctx->hCam, "TriggerSoftware") : MV_OK;
+  if(setTriggerMode == MV_TRIGGER_MODE_ON) sw_thrd_delay(1000); // 软触发后, 延时一秒, 等待相机执行一次拍照
 
   // 2, 等待获取图像
   if(MV_OK == ret)
@@ -144,7 +160,6 @@ int TakePhoto(EImgType imgType, const char *saveImgPath, int timeout, SImgMark *
     goto end_p;
   }
 
-  char name[MAX_LINE_CHARS]; // 存放相机制造商名字
 findp:
   pDevInfo = devList.pDeviceInfo[index++];
   if(!pDevInfo)
@@ -154,26 +169,27 @@ findp:
     goto end_p;
   }
 
-  name[0] = '\0'; if(0) ;
+  ctx.manuName[0] = '\0'; if(0) ;
   else if(pDevInfo->nTLayerType == MV_USB_DEVICE /*U口相机*/)
   {
-    strcpy(name, (const char *)pDevInfo->SpecialInfo.stUsb3VInfo.chManufacturerName);
+    strcpy(ctx.manuName, (const char *)pDevInfo->SpecialInfo.stUsb3VInfo.chManufacturerName);
+    ctx.camType = MV_USB_DEVICE;
     strcpy(imgMark.camModelName, (const char *)pDevInfo->SpecialInfo.stUsb3VInfo.chModelName);
     strcpy(imgMark.camSerialNum, (const char *)pDevInfo->SpecialInfo.stUsb3VInfo.chSerialNumber);
   }
   else if(pDevInfo->nTLayerType == MV_GIGE_DEVICE/*G口相机*/)
   {
-    strcpy(name, (const char *)pDevInfo->SpecialInfo.stGigEInfo.chManufacturerName);
+    strcpy(ctx.manuName, (const char *)pDevInfo->SpecialInfo.stGigEInfo.chManufacturerName);
+    ctx.camType = MV_GIGE_DEVICE;
     strcpy(imgMark.camModelName, (const char *)pDevInfo->SpecialInfo.stGigEInfo.chModelName);
     strcpy(imgMark.camSerialNum, (const char *)pDevInfo->SpecialInfo.stGigEInfo.chSerialNumber);
-    if(GIGE_CAMERA_ANY_VENDOR && 0 != strcmp(name, manufacturer))
+    if(xstrcasecmp(ctx.manuName, manufacturer) != 0 && gige_3rd_manu_supported(ctx.manuName))
     {
-      sw_log_debug("[%s] 发现 \"%s\" 厂商的网口相机", MODULE_NAME, name);
-      setTriggerMode = MV_TRIGGER_MODE_OFF; strcpy(name, manufacturer); // 关闭触发模式, 视为海康的网口相机
+      setTriggerMode = MV_TRIGGER_MODE_OFF;
     }
   }
 
-  if(xstrcasecmp(name, manufacturer) != 0)
+  if(xstrcasecmp(ctx.manuName, manufacturer) != 0 && (ctx.camType != MV_GIGE_DEVICE || !gige_3rd_manu_supported(ctx.manuName)))
   {
     if(index < devList.nDeviceNum) goto findp;
     ret = -5;
@@ -400,9 +416,9 @@ findp:
     
     name[0] = '\0'; if(0) ;
     else if(pDevInfo && pDevInfo->nTLayerType == MV_USB_DEVICE /*U口相机*/) strcpy(name, (const char *)pDevInfo->SpecialInfo.stUsb3VInfo.chManufacturerName);
-    else if(pDevInfo && pDevInfo->nTLayerType == MV_GIGE_DEVICE/*G口相机*/) strcpy(name, (const char *)pDevInfo->SpecialInfo.stGigEInfo.chManufacturerName);
+    else if(pDevInfo && pDevInfo->nTLayerType == MV_GIGE_DEVICE/*G口相机*/) strcpy(name, (const char *)pDevInfo->SpecialInfo.stGigEInfo.chManufacturerName) ;
 
-    if(xstrcasecmp(name, manufacturer) == 0) cnt++;
+    if(xstrcasecmp(name, manufacturer) == 0 || (pDevInfo->nTLayerType == MV_GIGE_DEVICE && gige_3rd_manu_supported(name))) cnt++;
     if(index < devList.nDeviceNum) goto findp;
     else ret = cnt;
   }

+ 2 - 0
hk_takephoto/takephoto_test.c

@@ -29,6 +29,8 @@ int main(int argc,char *argv[])
     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;

+ 2 - 0
tests/hk_takephoto/main.go

@@ -41,6 +41,8 @@ func main() {
 		} else {
 			baseapp.Logger.Errorf("拍照时发生错误: %v, 用时: %dms, 请修复所有问题后重试!!", err, elapsed)
 		}
+
+		time.Sleep(1 * time.Second) // 轮询拍照测试时, 给系统预留一定的相机释放时间
 	}
 	baseapp.Logger.Info("拍照测试任务结束")
 }