海康工业相机拍照代码(3)

本代码实现海康工业相机拍照并保存功能(MV_CC_ConvertPixelType)。
参考:MVS/MVS/Development/Documentations/海康工业相机SDK使用手册.chm

  • C接口定义
    • 图像处理
      • MV_CC_ConvertPixelType
void CMvCamera::grabLoop()
{
	cv::Mat frame;
	int bytesPerPixel;
	int frameCounter = -1;

	// ============================= 初始化 =============================
	int nRet = -1;                            // 初始化 nRet
	void* m_handle = NULL;                    // 初始化 m_handle
	MV_CC_DEVICE_INFO m_stDevInfo = { 0 };    // 初始化一台设备 m_stDevInfo
	MVCC_INTVALUE stIntvalue = { 0 };         // 初始化一帧数据 stIntvalue
	unsigned char* pFrameBuf = NULL;          // 定义图像缓存 pFrameBuf
	MV_FRAME_OUT_INFO_EX stInfo;              // 定义图像 stInfo
	unsigned char *pDataForRGB = NULL;        // 定义 RGB 像素格式
	// ============================= 初始化 =============================

	memcpy(&m_stDevInfo, m_capture, sizeof(MV_CC_DEVICE_INFO));    // 复制设备地址

	nRet = MV_CC_CreateHandle(&m_handle, &m_stDevInfo);            // 创建句柄
	if (MV_OK != nRet) qDebug() << "error: CreateHandle fail in grabLoop" << endl;
	else qDebug() << "CreateHandle success in grabLoop" << endl;

	nRet = MV_CC_OpenDevice(m_handle);                             // 连接设备
	if (MV_OK != nRet) qDebug() << "error: OpenDevice fail in grabLoop" << endl;
	else qDebug() << "OpenDevice success in grabLoop" << endl;

	// ======================================== 预设相机属性 ========================================
	nRet = MV_CC_SetEnumValue(m_handle, "TriggerMode", MV_TRIGGER_MODE_OFF); // 关闭触发源,设置连续模式
	nRet = MV_CC_SetEnumValue(m_handle, "ExposureAuto", 2);                  // 设置自动曝光
	//nRet = MV_CC_SetEnumValue(m_handle, "ExposureMode", 0);                // 设置曝光模式
	//nRet = MV_CC_SetEnumValue(m_handle, "ExposureTime", 900000.0);         // 设置曝光时间
	nRet = MV_CC_SetEnumValue(m_handle, "GainAuto", 2);                      // 设置自动增益
	nRet = MV_CC_SetEnumValue(m_handle, "BalanceWhiteAuto", 1);              // 设置自动白平衡
	if (MV_OK != nRet) printf("error: Properties preset fail in plugin [%x]\n", nRet);
	else qDebug() << "Properties preset sucess in plugin" << endl;
	// ====================================== 相机属性预设结束 ====================================== 

	nRet = MV_CC_StartGrabbing(m_handle);                           // 开始采集图像
	if (MV_OK != nRet) qDebug() << "error: StartGrabbing fail in grabLoop" << endl;
	else qDebug() << "StartGrabbing success in grabLoop" << endl;

	nRet = MV_CC_GetIntValue(m_handle, "PayloadSize", &stIntvalue); // 获取一帧数据的大小
	int nBufSize = stIntvalue.nCurValue;                            // 定义一帧数据大小
	pFrameBuf = (unsigned char*)malloc(nBufSize);                   // 动态分配图像缓存 memory allocation
	memset(&stInfo, 0, sizeof(MV_FRAME_OUT_INFO_EX));               // 初始化图像 stInfo

	// 丢掉前几帧
	for (int i = 0; i < 40; i++) {
		nRet = MV_CC_GetOneFrameTimeout(m_handle, pFrameBuf, nBufSize, &stInfo, 500);
		//continue;
	}

	while (!m_stopThreadRequested && m_capture) {

		/// thread safe
		//QMutexLocker locker(&m_mutex);
		if (!m_mutex.tryLock(100))
		{
			continue;
		}
		/ grab & retrieve next frame

		nRet = MV_CC_GetOneFrameTimeout(m_handle, pFrameBuf, nBufSize, &stInfo, 500);

		if (MV_OK != nRet)
		{
			Sleep(10);
		}
		else {
			/*
			MV_SAVE_IMG_TO_FILE_PARAM stParam;        // 定义输入数据保存文件参数
			stParam.enImageType = MV_Image_Png;       // 需要保存的图像类型,支持 MV_Image_Jpeg,MV_Image_Bmp,MV_Image_Tif
			stParam.enPixelType = stInfo.enPixelType; // 输入像素格式
			stParam.nWidth = stInfo.nWidth;           // 图像宽
			stParam.nHeight = stInfo.nHeight;         // 图像高
			stParam.nDataLen = stInfo.nFrameLen;      // 输入数据大小
			stParam.pData = pFrameBuf;                // 输入数据缓存
			stParam.nQuality = 1;			          // jpg图像质量范围为(50-99], png图像质量范围为[0-9]
			stParam.iMethodValue = 0;
			*/

			// 像素格式转换
			pDataForRGB = (unsigned char*)malloc(stInfo.nWidth * stInfo.nHeight * 3);
			unsigned int nDataSizeForRGB = stInfo.nWidth * stInfo.nHeight * 3;
			MV_CC_PIXEL_CONVERT_PARAM stConvertParam = { 0 };         	    // 定义像素格式转换输入输出参数
			memset(&stConvertParam, 0, sizeof(MV_CC_PIXEL_CONVERT_PARAM));
			// 源数据    
			stConvertParam.nWidth = stInfo.nWidth;                          // 图像宽 
			stConvertParam.nHeight = stInfo.nHeight;                        // 图像高 
			stConvertParam.pSrcData = pFrameBuf;                            // 输入数据缓存  
			stConvertParam.nSrcDataLen = stInfo.nFrameLen;                  // 输入数据大小 
			stConvertParam.enSrcPixelType = stInfo.enPixelType;             // 输入数据像素格式 
			// 目标数据
			stConvertParam.enDstPixelType = PixelType_Gvsp_BGR8_Packed;     // 输出像素格式 
			stConvertParam.pDstBuffer = pDataForRGB;                        // 输出数据缓存 
			stConvertParam.nDstBufferSize = nDataSizeForRGB;                // 输出缓存大小 
			nRet = MV_CC_ConvertPixelType(m_handle, &stConvertParam);


		    // 原 OpenCV 读图方法
			switch (frame.type()) {
			case CV_8UC3:    // (0-255)
				bytesPerPixel = 3;
				break;
			case CV_16UC3:   // (0-65535)
				bytesPerPixel = 3;
				break;
			default:
				bytesPerPixel = 3;
			}

			bytesPerPixel = 3;
			mCurrentImage = getNextBufferImage(stInfo.nWidth, stInfo.nHeight, 0, 0, bytesPerPixel);

			/// copy data
			mCurrentImage->setBuffer(pDataForRGB);

			/// set image number
			mCurrentImage->setNumber(++frameCounter);

			m_lastRetrievedImage = &mCurrentImage;

			/// notify
			emit newImageReceived(mCurrentImage);
		}

		m_mutex.unlock();
	}


	qDebug() << "acquired" << frameCounter << "images";

	if (!m_stopThreadRequested)
	{
		/// if we stopped because of some error, notify
		stopAcquisition();

		nRet = MV_CC_StopGrabbing(m_handle);   	// 停止采集图像
		if (MV_OK != nRet) qDebug() << "error: StopGrabbing fail in grabLoop" << endl;
		else qDebug() << "StopGrabbing success in grabLoop" << endl;

		nRet = MV_CC_CloseDevice(m_handle);   	// 关闭设备,释放资源
		if (MV_OK != nRet) qDebug() << "error: CloseDevice fail in grabLoop" << endl;
		else qDebug() << "CloseDevice success in grabLoop" << endl;

		nRet = MV_CC_DestroyHandle(m_handle);   // 销毁句柄,释放资源
		if (MV_OK != nRet) qDebug() << "error: DestroyHandle fail in grabLoop" << endl;
		else qDebug() << "DestroyHandle success in grabLoop" << endl;

		if (m_handle != NULL) {
			MV_CC_DestroyHandle(m_handle);
			m_handle = NULL;
		}

		// 释放图像缓存
		free(pFrameBuf);
		free(pDataForRGB);
		pFrameBuf = NULL;
		pDataForRGB = NULL;
	}
}

  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值