Matrox MIL图像采集卡使用QT获取图像

//MilCC.h
#pragma once
#pragma execution_character_set("utf-8")

#include <QThread.h>
#include <Mil.h>
#include <QDebug>
#include <QImage>
#include <QFileInfo>
#include <QMutex>
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#include <imgproc\imgproc_c.h>
#include <functional>

#pragma comment(lib, "opencv_core231.lib")
#pragma comment(lib, "opencv_highgui231.lib")
#pragma comment(lib, "opencv_imgproc231.lib")
#pragma comment(lib, "mil.lib")

using namespace cv;

/*公司所使用MIL采集卡,最大支持通道数2,有4个孔,但是只有2个可以使用,
API实在是看不懂,两块采集卡,一起使用,指定设备为第二个,还是默认第一个
,实在是搞不懂这个东西,太坑了,能用就行了.*/
#define MIL_MIN_CHANNEL_COUNT 1

#define MIL_MAX_CHANNEL_COUNT 2

/*固定宽度*/
#define MIL_WIDTH 640

/*固定高度*/
#define MIL_HEIGTH 480

class MilCC;

typedef void(MilCC::*QTIMAGE)(const int&, const QImage&);
typedef void(MilCC::*CVIMAGE)(const int&, const IplImage*);

/*信号类型*/
enum class SignalType {
	/*QT图像信号*/
	ST_QTIMAGE,

	/*CV图像信号*/
	ST_CVIMAGE,
	
	/*QT+CV图像信号*/
	ST_ALL
};

class MilCC : public QThread
{
	Q_OBJECT
public:
	/*构造*/
	MilCC();

	explicit MilCC(const SignalType& types);

	/*析构*/
	~MilCC();

	/*使用拷贝构造不安全,需要将其删除*/
	MilCC(const MilCC&) = delete;

	/*使用赋值构造不安全,需要将其删除*/
	MilCC& operator=(const MilCC&) = delete;

	/*获取错误信息*/
	const QString& getLastError();

	/*CV图像转QT图像*/
	void cvImageToQtImage(const IplImage* cv, QImage& qt);

	/*打开多个通道*/
	bool openDevices(const QString& dcfFile, const int& channelCount);

	/*打开一个通达*/
	bool openDevice(const QString& dcfFile, const int& channelID);

	/*关闭设备*/
	void closeDevice();

	/*开始采集*/
	bool startCapture();

	/*设置信号类型*/
	void setSignalType(const SignalType& types);

	/*获取信号类型*/
	const SignalType& getSignalType();

	/*停止采集*/
	bool stopCapture(bool hint = false);

	/*退出采集*/
	void quitCapture();

	/*获取IPL图像*/
	const IplImage* getIplImage(const int& channelID);

	/*设置抓图延时*/
	void setCaptureDelay(const int& delay);

	/*设置白平衡,需再打开设备之前操作*/
	void setWhiteBlance(bool enable);

	/*获取通道数*/
	inline const int getChannelCount() { return m_channelCount; };
	
	/*设置MIL测试*/
	void setMilTest(bool enable);

	/*创建CV图像用来给MIL采集卡使用*/
	IplImage* createCvImageForMil();
protected:
	/*设置最终错误*/
	void setLastError(const QString& error);

	/*设置通道图像*/
	void setChannelImage(const int& id);

	/*线程*/
	virtual void run() override;
private:
	QString m_lastError = "No Error";

	bool m_quit = false;

	bool m_start = false;

	bool m_isOpen = false;

	bool m_useWhiteBlance = true;

	const MIL_INT MilCC::m_channel[16] = {
		M_CH0, M_CH1, M_CH2,  M_CH3,
		M_CH4, M_CH5, M_CH6,  M_CH7,
		M_CH8, M_CH9, M_CH10, M_CH11,
		M_CH12, M_CH13, M_CH14, M_CH15
	};

	const MIL_INT MilCC::m_device[4] = {
		M_DEV0, M_DEV1, M_DEV2, M_DEV3
	};

	MIL_ID m_app = 0, m_system = 0, m_display = 0;
	
	MIL_ID m_digId[MIL_MAX_CHANNEL_COUNT] = { 0 };

	MIL_ID m_images[MIL_MAX_CHANNEL_COUNT] = { 0 };

	int m_channelCount = -1;

	int m_channelID = -1;

	IplImage* m_imageSrc[MIL_MAX_CHANNEL_COUNT] = { 0 };

	IplImage* m_cvTempImage = nullptr;

	QImage m_qtTempImage;

	int m_captureDelay = 40;

	CvFont m_stopFont;

	bool m_milTest = false;

	SignalType m_signalType = SignalType::ST_QTIMAGE;

	QMutex m_mutex;
signals:
	void getChannelImageSignal(const int& channelID, const QImage& image);

	void getChannelImageSignal(const int& channelID, const IplImage* image);
};
//MilCC.cpp
#include "MilCC.h"

MilCC::MilCC()
{
	for (int i = 0; i < MIL_MAX_CHANNEL_COUNT; i++)
	{
		m_imageSrc[i] = createCvImageForMil();
	}

	m_cvTempImage = createCvImageForMil();
	cvInitFont(&m_stopFont, CV_FONT_HERSHEY_PLAIN, 10.0f, 1.0f, 0, 2);
}

MilCC::MilCC(const SignalType& types)
{
	for (int i = 0; i < MIL_MAX_CHANNEL_COUNT; i++)
	{
		m_imageSrc[i] = createCvImageForMil();
	}

	m_cvTempImage = createCvImageForMil();
	cvInitFont(&m_stopFont, CV_FONT_HERSHEY_PLAIN, 10.0f, 1.0f, 0, 2);
	m_signalType = types;
}

MilCC::~MilCC()
{
	m_quit = true;

	if (m_isOpen)
	{
		closeDevice();
	}

	for (int i = 0; i < MIL_MAX_CHANNEL_COUNT; i++)
	{
		cvReleaseImage(&m_imageSrc[i]);
	}
	cvReleaseImage(&m_cvTempImage);
}

const QString& MilCC::getLastError()
{
	return m_lastError;
}

void MilCC::cvImageToQtImage(const IplImage* cv, QImage& qt)
{
	if (!cv || qt.isNull())
		return;
	m_mutex.lock();
	cvCopy(cv, m_cvTempImage);
	cvCvtColor(m_cvTempImage, m_cvTempImage, CV_BGR2RGB);
	qt = QImage((uchar*)m_cvTempImage->imageData, m_cvTempImage->width, m_cvTempImage->height, m_cvTempImage->widthStep, QImage::Format_RGB888);
	m_mutex.unlock();
}

bool MilCC::openDevices(const QString& dcfFile, const int& channelCount)
{
	bool result = false;
	do
	{
		if (m_milTest)
		{
			result = true;
			break;
		}

		if (m_isOpen)
		{
			setLastError("采集卡设备已打开");
			break;
		}

		if (channelCount < MIL_MIN_CHANNEL_COUNT || channelCount > MIL_MAX_CHANNEL_COUNT)
		{
			setLastError("MIL采集卡最大通道数仅支持2个通道");
			break;
		}

		if (!QFileInfo(dcfFile).exists())
		{
			setLastError(QString("%1文件不存在").arg(dcfFile));
			break;
		}

		MappAllocW(M_DEFAULT, &m_app);
		MsysAlloc(M_SYSTEM_MORPHIS, M_DEF_SYSTEM_NUM, M_SETUP, &m_system);
		MsysControl(m_system, M_TIMEOUT, 1);
		MappControl(M_ERROR, M_PRINT_DISABLE);

		for (int i = 0; i < channelCount; i++)
		{
			MdigAllocA(m_system, m_device[i], dcfFile.toLocal8Bit().data(), M_DEFAULT, &m_digId[i]);
			if (m_digId[i] == M_NULL)
			{
				setLastError(QString("请检查是否有其他应用程序占用MOR采集卡.MOR设备[%1]错误").arg(m_device[i]));
				break;
			}

			MdigControl(m_digId[i], M_GRAB_TIMEOUT, 1000);
			MdigControl(m_digId[i], M_GRAB_MODE, M_SYNCHRONOUS);

			if (m_useWhiteBlance)
			{
				MdigControl(m_digId[i], M_GRAB_AUTOMATIC_INPUT_GAIN, M_DISABLE);
				MdigControl(m_digId[i], M_GRAB_INPUT_GAIN, 50);
			}

			MbufAllocColor(m_system,
				MdigInquire(m_digId[i], M_SIZE_BAND, M_NULL),
				MdigInquire(m_digId[i], M_SIZE_X, M_NULL),
				MdigInquire(m_digId[i], M_SIZE_Y, M_NULL),
				8L + M_UNSIGNED, M_IMAGE + M_BASIC_BUFFER_PURPOSE,
				&m_images[i]);

			MbufClear(m_images[i], 0);
			MdigControl(m_digId[i], M_CAMERA_LOCK, M_DISABLE);
			MdigControl(m_digId[i], M_CHANNEL, m_channel[i]);
			MdigControl(m_digId[i], M_CAMERA_LOCK, M_ENABLE);
			MdigGrabContinuous(m_digId[i], m_images[i]);
		}
		m_channelCount = channelCount;
		m_channelID = -1;
		result = m_isOpen = true;
	} while (false);
	return result;
}

bool MilCC::openDevice(const QString& dcfFile, const int& channelID)
{
	bool result = false;
	do
	{
		if (m_milTest)
		{
			result = true;
			break;
		}

		if (m_isOpen)
		{
			setLastError("采集卡设备已打开");
			break;
		}

		if (channelID < MIL_MIN_CHANNEL_COUNT - 1 || channelID > MIL_MAX_CHANNEL_COUNT - 1)
		{
			setLastError("MIL采集卡最大通道数仅支持2个通道");
			break;
		}

		if (!QFileInfo(dcfFile).exists())
		{
			setLastError(QString("%1文件不存在").arg(dcfFile));
			break;
		}

		MappAllocW(M_DEFAULT, &m_app);
		MsysAlloc(M_SYSTEM_MORPHIS, M_DEF_SYSTEM_NUM, M_SETUP, &m_system);
		MsysControl(m_system, M_TIMEOUT, 1);
		MappControl(M_ERROR, M_PRINT_DISABLE);

		MdigAllocA(m_system, m_device[0], dcfFile.toLocal8Bit().data(), M_DEFAULT, &m_digId[0]);
		if (m_digId[0] == M_NULL)
		{
			setLastError(QString("请检查是否有其他应用程序占用MOR采集卡.MOR设备[%1]错误").arg(m_device[0]));
			break;
		}

		MdigControl(m_digId[0], M_GRAB_TIMEOUT, 1000);
		MdigControl(m_digId[0], M_GRAB_MODE, M_SYNCHRONOUS);

		if (m_useWhiteBlance)
		{
			MdigControl(m_digId[0], M_GRAB_AUTOMATIC_INPUT_GAIN, M_DISABLE);
			MdigControl(m_digId[0], M_GRAB_INPUT_GAIN, 50);
		}

		MbufAllocColor(m_system,
			MdigInquire(m_digId[0], M_SIZE_BAND, M_NULL),
			MdigInquire(m_digId[0], M_SIZE_X, M_NULL),
			MdigInquire(m_digId[0], M_SIZE_Y, M_NULL),
			8L + M_UNSIGNED, M_IMAGE + M_BASIC_BUFFER_PURPOSE,
			&m_images[0]);

		MbufClear(m_images[0], 0);
		MdigControl(m_digId[0], M_CAMERA_LOCK, M_DISABLE);
		MdigControl(m_digId[0], M_CHANNEL, m_channel[channelID]);
		MdigControl(m_digId[0], M_CAMERA_LOCK, M_ENABLE);
		MdigGrabContinuous(m_digId[0], m_images[0]);
		m_channelCount = 1;
		m_channelID = channelID;
		result = m_isOpen = true;
	} while (false);
	return result;
}

void MilCC::closeDevice()
{
	do
	{
		if (!m_isOpen)
		{
			setLastError("设备未打开");
			break;
		}

		for (int i = 0; i < m_channelCount; i++)
		{
			MdigHalt(m_digId[i]);
			MbufFree(m_images[i]);
			MdigFree(m_digId[i]);
		}

		MsysFree(m_system);
		MappFree(m_app);

		m_isOpen = false;
		m_channelCount = -1;
		m_channelID = -1;
	} while (false);
	return;
}

bool MilCC::startCapture()
{
	bool result = false;
	do
	{
		if (!m_isOpen)
		{
			setLastError("设备未打开");
			break;
		}

		m_start = true;

		if (!this->isRunning())
		{
			this->start();
		}
		result = true;
	} while (false);
	return result;
}

void MilCC::setSignalType(const SignalType& types)
{
	m_signalType = types;
}

const SignalType& MilCC::getSignalType()
{
	return m_signalType;
}

bool MilCC::stopCapture(bool hint)
{
	bool result = false;
	do
	{
		if (!m_isOpen)
		{
			setLastError("设备未打开");
			break;
		}

		QImage qimage;
		m_start = false;
		if (!hint)
		{
			result = true;
			break;
		}

		for (int i = 0; i < m_channelCount; i++)
		{
			cvPutText(m_imageSrc[i], "STOP", cvPoint(MIL_WIDTH / 2 - 100, MIL_HEIGTH / 2), &m_stopFont, CV_RGB(255, 255, 0));
			setChannelImage(i);
		}
		result = true;
	} while (false);
	return result;
}

void MilCC::quitCapture()
{
	m_quit = true;
}

const IplImage* MilCC::getIplImage(const int& channelID)
{
	return m_imageSrc[channelID];
}

void MilCC::setCaptureDelay(const int& delay)
{
	m_captureDelay = delay;
}

void MilCC::setWhiteBlance(bool enable)
{
	m_useWhiteBlance = enable;
}

void MilCC::setMilTest(bool enable)
{
	m_milTest = enable;
}

IplImage* MilCC::createCvImageForMil()
{
	return cvCreateImage(cvSize(MIL_WIDTH, MIL_HEIGTH), 8, 3);
}

void MilCC::setLastError(const QString& error)
{
#ifdef QT_DEBUG
	qDebug() << __FUNCTION__ << error << endl;
#endif
	m_lastError = error;
}

void MilCC::setChannelImage(const int& id)
{
	switch (m_signalType)
	{
	case SignalType::ST_QTIMAGE:
		cvImageToQtImage(m_imageSrc[id], m_qtTempImage);
		emit getChannelImageSignal(m_channelID == -1 ? id : m_channelID, m_qtTempImage);
		break;
	case SignalType::ST_CVIMAGE:
		emit getChannelImageSignal(m_channelID == -1 ? id : m_channelID, m_imageSrc[id]);
		break;
	case SignalType::ST_ALL:
		cvImageToQtImage(m_imageSrc[id], m_qtTempImage);
		emit getChannelImageSignal(m_channelID == -1 ? id : m_channelID, m_qtTempImage);
		emit getChannelImageSignal(m_channelID == -1 ? id : m_channelID, m_imageSrc[id]);
		break;
	default:
		break;
	}
}

void MilCC::run()
{
	while (!m_quit)
	{
		if (m_start)
		{
			for (int i = 0; i < m_channelCount; i++)
			{
				MbufGetColor(m_images[i], M_PACKED + M_BGR24, M_ALL_BANDS, m_imageSrc[i]->imageData);
				MbufClear(m_images[i], 0);
				setChannelImage(i);
			}
		}
		msleep(m_captureDelay);
	}
	quit();
}

第二种方法:

/*MIL采集卡线程*/
	class Mil : public QThread {
		Q_OBJECT
	public:
		/*构造*/
		explicit Mil(QObject* parent = nullptr);

		/*析构*/
		~Mil();

		/*打开MIL设备驱动*/
		bool open(const QString& name, const int& channel);

		/*关闭MIL设备驱动*/
		void close();

		/*是否打开*/
		bool isOpen();

		/*开始采集*/
		void startCapture();

		/*结束采集*/
		void endCapture();

		/*获取错误信息*/
		const QString& getLastError();
	protected:
		/*重写run*/
		virtual void run();

		/*设置错误*/
		void setLastError(const QString& error);
	private:
		/*父线程指针*/
		Dt::Function* m_function = nullptr;

		/*MIL定义*/
		MIL_ID MilApplication = M_NULL, MilSystem = M_NULL, MilDisplay = M_NULL;
		MIL_ID MilDigitizer = M_NULL, MilImage = M_NULL, MilImage0 = M_NULL, MilImage2D = M_NULL;

		/*保存错误信息*/
		QString m_lastError = "No Error";

		bool m_capture = false;

		bool m_quit = false;

		bool m_open = false;

		int m_channel[2] = { M_CH0,M_CH1 };
	};
void Cc::Mil::run()
{
	DEBUG_INFO_EX("MIL采集卡线程%lu已启动", (ulong)QThread::currentThreadId());
	QImage image;
	IplImage* currentImage = cvCreateImage(cvSize(m_function->m_cardConfig.width, m_function->m_cardConfig.height), 8, 3);
	if (!currentImage)
	{
		setLastError("currentImage分配内存失败");
		return;
	}

	while (!m_quit)
	{
		if (m_function->m_connect && m_capture)
		{
			MbufGetColor(MilImage, M_PACKED + M_BGR24, M_ALL_BANDS, currentImage->imageData);
			MbufClear(MilImage, 0);

			if (m_function->m_capture)
			{
				memcpy(m_function->m_cvAnalyze->imageData, currentImage->imageData, m_function->m_cardConfig.size);
				m_function->m_capture = false;
			}

			m_function->drawRectOnImage(currentImage);

			if (Misc::cvImageToQtImage(currentImage, &image))
			{
				m_function->updateImage(image);
			}
		}
		msleep(40);
	}
	cvReleaseImage(&currentImage);
	quit();
	DEBUG_INFO_EX("MIL采集卡线程%lu已退出", (ulong)QThread::currentThreadId());
	return;
}

void Cc::Mil::setLastError(const QString& error)
{
	DEBUG_INFO() << error;
	Misc::writeRunError(error);
	m_lastError = error;
}

Cc::Mil::Mil(QObject* parent)
{
	m_function = reinterpret_cast<Dt::Function*>(parent);
}

Cc::Mil::~Mil()
{
	if (m_open)
	{
		close();
	}

	if (isRunning())
	{
		wait(3000);
	}
	m_function = nullptr;
}

bool Cc::Mil::open(const QString& name, const int& channel)
{
	bool result = false;
	do
	{
		if (m_open)
		{
			result = true;
			break;
		}

		RUN_BREAK(channel < 0 || channel > 1, Q_SPRINTF("MIL采集卡通道编号为%d,不支持的通道编号", channel));

		MappControl(M_DEFAULT, M_ERROR, M_PRINT_DISABLE);//禁用对话框报错

		RUN_BREAK(!MappAlloc(M_DEFAULT, &MilApplication), "MappAlloc失败");

		RUN_BREAK(!MsysAlloc(M_SYSTEM_MORPHIS, M_DEF_SYSTEM_NUM, M_SETUP, &MilSystem), "MsysAlloc失败");

		RUN_BREAK(!MdigAllocA(MilSystem, M_DEFAULT, name.toLocal8Bit().data(), M_DEFAULT, &MilDigitizer), "MdigAlloc失败");

		MIL_INT miX = MdigInquire(MilDigitizer, M_SIZE_X, M_NULL);
		MIL_INT miY = MdigInquire(MilDigitizer, M_SIZE_Y, M_NULL);
		MIL_INT miBand = MdigInquire(MilDigitizer, M_SIZE_BAND, M_NULL);
		MbufAllocColor(MilSystem, miBand, miX, miY, 8L + M_UNSIGNED, M_IMAGE + M_BASIC_BUFFER_PURPOSE, &MilImage);
		MdigControl(MilDigitizer, M_GRAB_MODE, M_SYNCHRONOUS);
		MdigControl(MilDigitizer, M_CAMERA_LOCK, M_ENABLE);

		MdigControl(MilDigitizer, M_GRAB_AUTOMATIC_INPUT_GAIN, M_DISABLE);
		MdigControl(MilDigitizer, M_GRAB_INPUT_GAIN, 50);

		MappControl(M_ERROR, M_PRINT_DISABLE);

		MbufClear(MilImage, 0);

		RUN_BREAK(!MilDigitizer, "MilDigitizer失败");

		MdigControl(MilDigitizer, M_CAMERA_LOCK, M_DISABLE);
		MdigControl(MilDigitizer, M_CHANNEL, m_channel[channel]);
		MdigControl(MilDigitizer, M_CAMERA_LOCK, M_ENABLE);
		MdigGrabContinuous(MilDigitizer, MilImage);
		m_quit = false;
		result = true;
		m_open = true;
	} while (false);
	return result;
}

void Cc::Mil::close()
{
	m_open = false;
	m_quit = true;
	if (MilDigitizer) MdigHalt(MilDigitizer);
	if (MilImage) MbufFree(MilImage);
	if (MilDigitizer) MdigFree(MilDigitizer);
	if (MilSystem) MsysFree(MilSystem);
	if (MilApplication) MappFree(MilApplication);
}

bool Cc::Mil::isOpen()
{
	return m_open;
}

void Cc::Mil::startCapture()
{
	if (!this->isRunning())
	{
		this->start();
	}
	m_capture = true;
}

void Cc::Mil::endCapture()
{
	m_capture = false;
}

const QString& Cc::Mil::getLastError()
{
	return m_lastError;
}

第三种方法(建议使用,此类库为一个采集卡基类+子类架构,代码量可能比较多):
//CapBase.h
#pragma once
#pragma execution_character_set("utf-8")

#include <QObject>
#include <QTimer>
#include <QPixmap>
#include <QImage>
#include <QMutex>
#include <QDir>
#include <QDebug>
#include <QThread>

#include <functional>

#include <ImageProcess/ImageProcess.h>
#ifdef _WIN64
#pragma comment(lib, "ImageProcess_X64.lib")
#else
#pragma comment(lib, "ImageProcess.lib")
#endif

/*
* @brief,位图信号
*/
#define QPIX_SIGNAL \
static_cast<void (CapBase::*)(const QPixmap&)>(&CapBase::updateImageSignal)

/*
* @brief,图像信号
*/
#define QIMG_SIGNAL \
static_cast<void (CapBase::*)(const QImage&)>(&CapBase::updateImageSignal)

class CapBase : public QThread {
	Q_OBJECT
public:
	/*
	* @brief,构造
	*/
	CapBase(QObject* parent = Q_NULLPTR);

	/*
	* @brief,析构
	*/
	virtual ~CapBase();

	/*
	* @brief,获取最终错误
	* @return,QString
	*/
	QString getLastError() const;

	/*
	* @brief,设置采集卡名称
	* @param1,采集卡名称
	* @return,void
	*/
	void setCardName(const QString& name);

	/*
	* @brief,获取采集卡名称
	* @return,QString
	*/
	QString getCardName() const;

	/*
	* @brief,设置图像原始大小
	* @param1,宽度
	* @param2,高度
	* @return,void
	*/
	void setImageOriginalSize(int width, int height);

	/*
	* @brief,获取图像原始大小
	* @return,cv::Size
	*/
	cv::Size getImageOriginalSize() const;

	/*
	* @brief,设置图像缩放大小
	* @param1,宽度
	* @param2,高度
	* @return,bool
	*/
	bool setImageScaleSize(int width, int height);

	/*
	* @brief,获取图像缩放大小
	* @return,cv::Size
	*/
	cv::Size getImageScaleSize() const;

	/*
	* @brief,打开
	* @param1,设备ID
	* @return,bool
	*/
	virtual bool open(int id) = 0;

	/*
	* @brief,关闭设备
	* @return,bool
	*/
	virtual bool close() = 0;

	/*
	* @brief,是否打开
	* @return,bool
	*/
	bool isOpen() const;

	/*
	* @brief,开始采集
	* @return,bool
	*/
	virtual bool startCapture();

	/*
	* @brief,停止采集
	* @return,bool
	*/
	virtual bool stopCapture();

	/*
	* @brief,设置采集间隔
	* @param1,间隔(ms)
	* @return,void
	*/
	void setInterval(int interval);

	/*
	* @brief,获取采集间隔
	* @return,int
	*/
	int getInterval() const;

	/*
	* @brief,获取原始图像
	* @return,Mat&
	*/
	cv::Mat& getSourceImage();

	/*
	* @brief,获取缩放图像
	* @return,Mat&
	*/
	cv::Mat& getScaledImage();

	/*
	* @brief,获取原始图像
	* @return,QImage&
	*/
	QImage& getSourceImage(int);

	/*
	* @brief,获取缩放图像
	* @return,QImage&
	*/
	QImage& getScaledImage(int);

	/*
	* @brief,设置图像处理
	* @param1,lambda
	* @return,void
	*/
	void setImageProc(std::function<void(cv::Mat& mat)> proc);

	/*
	* @brief,获取图像处理
	* @return,std::function<void(cv::Mat& mat)>
	*/
	std::function<void(cv::Mat& mat)> getImageProc() const;

	/*
	* @brief,设置缩放大小位置
	* @notice,setImageProc处理缩放图像大小的前后
	* @param1,true缩放在前,false缩放在后
	* @return,void
	*/
	void setScaleSizePos(bool pos);

	/*
	* @brief,获取缩放大小位置
	* @return,bool
	*/
	bool getScaleSizePos() const;

	/*
	* @brief,设置信号类型
	* @param1,0->QPixmap Signal
	*		  1->QImage Signal
	*		  2->QPixmap&QImage
	*         3->No Signal
	* @return,void
	*/
	void setSignalType(int signalType = 0);

	/*
	* @brief,获取信号类型
	* @return,int
	*/
	int getSignalType() const;

	/*
	* @brief,设置无信号图像
	* @notice,默认为启用
	* @param1,是否启用
	*/
	void setNoSignalImage(bool enable);

	/*
	* @brief,是否有无信号图像
	* @return,bool
	*/
	bool isNoSignalImage() const;

	/*
	* @brief,设置缩放图像
	* @param1,是否启用
	* @return,void
	*/
	void setScaledImage(bool on);

	/*
	* @brief,获取缩放图像
	* @return,bool
	*/
	bool getScaledImage() const;

	/*
	* @brief,设置配置文件路径
	* @param1,文件路径
	* @return,void
	*/
	void setConfigFilePath(const QString& filePath);

	/*
	* @brief,获取配置文件路径
	* @return,void
	*/
	QString getConfigFilePath() const;

	/*
	* @brief,设置转换处理
	* @notice,如果设置了此函数的处理方式,将不会使用matToQImage内部的转换
	* @param1,转换处理函数
	* @return,void
	*/
	void setConvertProc(std::function<QImage(const cv::Mat& mat)> proc);

	/*
	* @brief,获取转换处理
	* @return,std::function<QImage(const cv::Mat& mat)>
	*/
	std::function<QImage(const cv::Mat& mat)> getConvertProc() const;

protected:
	/*
	* @brief,设置最终错误
	* @param1,最终错误
	* @return,void
	*/
	void setLastError(const QString& error);

	/*
	* @brief,mat图像转Qt图像[重载1]
	* @param1,mat
	* @param2,qimage
	* @return,bool
	*/
	bool matToQImage(const cv::Mat& mat, QImage& image) const;

	/*
	* @brief,mat图像转Qt图像[重载二]
	* @param1,mat
	* @return,void
	*/
	QImage matToQImage(const cv::Mat& mat) const;

	/*
	* @brief,缩放图像大小
	* @param1,mat
	* @return,bool
	*/
	bool scaledImageSize(cv::Mat& mat) const;

	/*
	* @brief,缩放图像大小
	* @param1,QImage
	* @return,bool
	*/
	bool scaledImageSize(QImage& img) const;

	/*
	* @brief,发射更新图像信号
	* @param1,cv::Mat
	* @return,void
	*/
	void emitUpdateImageSignal(const cv::Mat& mat);

	/*
	* @brief,发送无信号图像
	* @param1,多少秒之后发送[如果设置为0,则直接发送]
	* @return,void
	*/
	void sendNoSignalImage(int afterMsSend = 100);

	/*
	* @brief,获取图像实际宽度
	* @return,cv::Size
	*/
	cv::Size getImageRealSize() const;

	/*
	* @brief,处理图像
	* @return,void
	*/
	void processImage();

	/*
	* @brief,生成配置文件名
	* @param1,文件名
	* @return,bool
	*/
	bool generateConfigFileName(const QString& fileName);
protected:
	/*
	* @m_mat,从设备读取的数据存到mat中
	* @m_src,保留原始的图像
	* @m_sca,保留原始缩放的图像
	*/
	cv::Mat m_mat, m_src, m_sca;

	/*
	* @m_srcq,原始的QT图像
	* @m_scaq,缩放的QT图像
	*/
	QImage m_srcq, m_scaq;

	//采集间隔
	int m_interval = 30;

	//最终错误信息
	QString m_lastError = "未知错误";

	//采集卡名称
	QString m_cardName = "未知采集卡";

	//线程是否退出
	bool m_quit = false;

	//判断采集卡是否打开
	bool m_open = false;

	//是否开始抓图
	bool m_capture = false;

	//缩放大小位置
	bool m_scaleSizePos = true;

	//原始图像宽度
	int m_originalWidth = 1920;

	//原始图像高度
	int m_originalHeight = 1080;

	//当前图像宽度
	int m_currentWidth = 0;

	//当前图像高度
	int m_currentHeight = 0;

	//缩放图像宽度比例
	double m_scalew = 1.0f;

	//缩放图像高度比例
	double m_scaleh = 1.0f;

	//互斥锁
	QMutex m_mutex;

	//图像处理函数
	std::function<void(cv::Mat& mat)> m_imageProc = nullptr;

	//转换图像处理函数
	std::function<QImage(const cv::Mat& mat)> m_convertProc = nullptr;

	//信号类型
	int m_signalType = 0;

	//是否启用无信号图像
	bool m_noSignalImage = true;

	//是否启用缩放图像
	bool m_scaledImage = true;

	//配置文件路径
	QString m_configFilePath;

	//配置文件名称
	QString m_configFileName;

	//通道编号
	int m_channelId = 0;

signals:
	/*
	* @brief,更新图像信号[重载1]
	* @param1,QImage图像
	* @return,void
	*/
	void updateImageSignal(const QImage& image);

	/*
	* @brief,更新图像信号[重载2]
	* @param1,QPixmap图像
	* @return,void
	*/
	void updateImageSignal(const QPixmap& image);
};

//CapBase.cpp
#include "CapBase.h"

CapBase::CapBase(QObject* parent)
	:QThread(parent)
{

}

CapBase::~CapBase()
{
}

QString CapBase::getLastError() const
{
	return m_lastError;
}

void CapBase::setCardName(const QString& name)
{
	m_cardName = name;
}

QString CapBase::getCardName() const
{
	return m_cardName;
}

void CapBase::setImageOriginalSize(int width, int height)
{
	m_originalWidth = width;
	m_originalHeight = height;
}

cv::Size CapBase::getImageOriginalSize() const
{
	return cv::Size(m_originalWidth, m_originalHeight);
}

bool CapBase::setImageScaleSize(int width, int height)
{
	m_currentWidth = width;
	m_currentHeight = height;
	if (m_originalWidth <= 0 || m_originalHeight <= 0)
	{
		setLastError("图像宽度高度不可小于等于0");
		return false;
	}
	m_scalew = (double)width / m_originalWidth;
	m_scaleh = (double)height / m_originalHeight;
	return true;
}

cv::Size CapBase::getImageScaleSize() const
{
	return getImageRealSize();
}

bool CapBase::isOpen() const
{
	return m_open;
}

bool CapBase::startCapture()
{
	if (m_open)
	{
		m_capture = true;
	}
	return true;
}

bool CapBase::stopCapture()
{
	if (m_open)
	{
		m_capture = false;
		sendNoSignalImage();
	}
	return true;
}

void CapBase::setInterval(int interval)
{
	if (interval <= 0)
		return;

	m_interval = interval;
}

int CapBase::getInterval() const
{
	return m_interval;
}

cv::Mat& CapBase::getSourceImage()
{
	QMutexLocker locker(&m_mutex);
	m_src.release();
	if (!m_mat.empty())
		m_src = m_mat.clone();
	return m_src;
}

cv::Mat& CapBase::getScaledImage()
{
	QMutexLocker locker(&m_mutex);
	m_sca.release();
	if (!m_mat.empty())
	{
		m_sca = m_mat.clone();
		scaledImageSize(m_sca);
	}
	return m_sca;
}

QImage& CapBase::getSourceImage(int)
{
	QMutexLocker locker(&m_mutex);
	matToQImage(m_mat, m_srcq);
	return m_srcq;
}

QImage& CapBase::getScaledImage(int)
{
	QMutexLocker locker(&m_mutex);
	matToQImage(m_mat, m_scaq);
	scaledImageSize(m_scaq);
	return m_scaq;
}

void CapBase::setImageProc(std::function<void(cv::Mat& mat)> proc)
{
	m_imageProc = proc;
}

std::function<void(cv::Mat& mat)> CapBase::getImageProc() const
{
	return m_imageProc;
}

void CapBase::setScaleSizePos(bool pos)
{
	m_scaleSizePos = pos;
}

bool CapBase::getScaleSizePos() const
{
	return m_scaleSizePos;
}

void CapBase::setSignalType(int signalType)
{
	if (signalType < 0 || signalType > 3)
		return;
	m_signalType = signalType;
}

int CapBase::getSignalType() const
{
	return m_signalType;
}

void CapBase::setNoSignalImage(bool enable)
{
	m_noSignalImage = enable;
}

bool CapBase::isNoSignalImage() const
{
	return m_noSignalImage;
}

void CapBase::setScaledImage(bool on)
{
	m_scaledImage = on;
}

bool CapBase::getScaledImage() const
{
	return m_scaledImage;
}

void CapBase::setConfigFilePath(const QString& filePath)
{
	m_configFilePath = filePath;
}

QString CapBase::getConfigFilePath() const
{
	return m_configFilePath;
}

void CapBase::setConvertProc(std::function<QImage(const cv::Mat& mat)> proc)
{
	m_convertProc = proc;
}

std::function<QImage(const cv::Mat& mat)> CapBase::getConvertProc() const
{
	return m_convertProc;
}

void CapBase::setLastError(const QString& error)
{
	m_lastError = error;
}

bool CapBase::matToQImage(const cv::Mat& mat, QImage& image) const
{
	if (mat.empty())
	{
		image = QImage();
		return false;
	}

	if (m_convertProc)
	{
		image = m_convertProc(mat);
	}
	else
	{
		cv::Mat temp;
		cv::cvtColor(mat, temp, cv::COLOR_BGR2RGB);

		image = QImage(temp.data, temp.cols, temp.rows, QImage::Format_RGB888).
			copy(0, 0, temp.cols, temp.rows);
	}

	return true;
}

QImage CapBase::matToQImage(const cv::Mat& mat) const
{
	if (mat.empty())
		return QImage();

	if (m_convertProc)
	{
		return m_convertProc(mat);
	}

	cv::Mat temp;
	cv::cvtColor(mat, temp, cv::COLOR_BGR2RGB);
	return QImage(temp.data, temp.cols, temp.rows, QImage::Format_RGB888).
		copy(0, 0, temp.cols, temp.rows);
}

bool CapBase::scaledImageSize(cv::Mat& mat) const
{
	if (!m_scaledImage)
		return true;

	if (mat.empty())
		return false;

	cv::Size size = cv::Size(mat.cols * m_scalew, mat.rows * m_scaleh);
	cv::resize(mat, mat, size);
	return true;
}

bool CapBase::scaledImageSize(QImage& img) const
{
	if (!m_scaledImage)
		return true;

	if (img.isNull())
		return false;

	img.scaled(img.width() * m_scalew, img.height() * m_scaleh,
		Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
	return true;
}

void CapBase::emitUpdateImageSignal(const cv::Mat& mat)
{
	switch (m_signalType)
	{
	case 0:
		emit updateImageSignal(QPixmap::fromImage(matToQImage(mat)));
		break;
	case 1:
		emit updateImageSignal(matToQImage(mat));
		break;
	case 2:
		emit updateImageSignal(QPixmap::fromImage(matToQImage(mat)));
		emit updateImageSignal(matToQImage(mat));
		break;
	default:
		break;
	}
	return;
}

void CapBase::sendNoSignalImage(int afterMsSend)
{
	auto fnc = [&]() {
		if (!m_noSignalImage)
		{
			return;
		}

		cv::Size realSize = getImageRealSize();
		cv::Mat mat(realSize, CV_8UC3, CV_RGB(0, 0, 0));
		//std::string text = "No Signal";
		//double fontScale = 1.2;
		//int thickness = 2;
		//cv::Size size = cv::getTextSize(text, 0, fontScale, thickness, 0);
		//cv::Point point = { 0 };
		//point.x = realSize.width / 2 - size.width / 2;
		//point.y = realSize.height / 2 - size.height / 2;
		//cv::putText(mat, text, point, 0, fontScale, CV_RGB(255, 255, 255), thickness);
		emitUpdateImageSignal(mat);
		return;
	};
	afterMsSend ? QTimer::singleShot(afterMsSend, fnc) : fnc();
	return;
}

cv::Size CapBase::getImageRealSize() const
{
	if (m_currentWidth && m_currentHeight)
		return cv::Size(m_currentWidth, m_currentHeight);
	return cv::Size(m_originalWidth, m_originalHeight);
}

void CapBase::processImage()
{
	cv::Mat mat = m_mat.clone();

	if (m_scaleSizePos)
		scaledImageSize(mat);

	if (m_imageProc)
		m_imageProc(mat);

	if (!m_scaleSizePos)
		scaledImageSize(mat);

	emitUpdateImageSignal(mat);

	return;
}

bool CapBase::generateConfigFileName(const QString& fileName)
{
	bool result = false;
	do 
	{
		m_configFilePath = m_configFilePath.isEmpty() ?
			"Config" : m_configFilePath;

		if (!QDir(m_configFilePath).exists())
		{
			if (!QDir().mkpath(m_configFilePath))
			{
				setLastError(QString("创建采集卡配置文件夹%1失败").arg(m_configFilePath));
				break;
			}
		}

		const auto ch = *(m_configFilePath.end() - 1);
		if (ch == '\\' || ch == '/')
			m_configFileName = m_configFilePath + fileName;
		else
			m_configFileName = QString("%1\\%2").arg(m_configFilePath, fileName);

		result = true;
	} while (false);
	return result;
}

//MilCap.h
#pragma once
#pragma execution_character_set("utf-8")

/*
*../代表是上层路径,大佬勿喷,有些刚学习的人可能不认识.
*/

#include "../CapBase.h"

class MilCap : public CapBase
{
	Q_OBJECT

public:
	MilCap(QObject* parent = nullptr);

	~MilCap();

	bool open(int id);

	bool close();

protected:
	void run();

protected:
	bool writeDcfFile();
private:
	static bool m_allocMil;

	static long m_application;

	static long m_system;

	long m_digitizer = 0;

	long m_image = 0;

	long m_channel[2] = { 0x40000000L,0x20000000L };

	static QMutex m_milMutex;
};
//MilCap.cpp
#include "MilCap.h"
#include <QFile>
#include <QFileInfo>

//这里是你调用的SDK MIL采集卡的头文件路径,根据你的路径进行设置
#include "../../../Dependent/Lib/MIL/include/Mil.h"

//这里是你调用的SDK MIL采集卡的库文件路径,根据你的路径进行设置
#pragma comment(lib, "../../Dependent/Lib/MIL/lib/mil.lib")

bool MilCap::m_allocMil = false;
MIL_INT MilCap::m_application = M_NULL;
MIL_INT MilCap::m_system = M_NULL;
QMutex MilCap::m_milMutex;

MilCap::MilCap(QObject* parent)
	: CapBase(parent)
{
	m_originalWidth = 640;

	m_originalHeight = 480;

	m_interval = 50;

	m_mat = cv::Mat(cv::Size(m_originalWidth, m_originalHeight), CV_8UC3);

	start();
}

MilCap::~MilCap()
{
	m_quit = true;
	wait(5000);
	QMutexLocker locker(&m_milMutex);
	if (m_allocMil)
	{
		if (m_system)
		{
			MsysFree(m_system);
			m_system = M_NULL;
		}

		if (m_application)
		{
			MappFree(m_application);
			m_application = M_NULL;
		}
		m_allocMil = false;
	}
}

bool MilCap::open(int id)
{
	bool result = false;
	do
	{
		if (id < 0 || id > 1)
		{
			setLastError("Mil采集卡仅支持通道0或1");
			break;
		}

		if (!writeDcfFile())
		{
			break;
		}

		QMutexLocker locker(&m_milMutex);
		if (!m_allocMil)
		{
			if (!MappAlloc(M_DEFAULT, &m_application))
			{
				setLastError("MappAlloc失败");
				break;
			}

			if (!MsysAlloc(M_SYSTEM_MORPHIS, M_DEF_SYSTEM_NUM, M_SETUP, &m_system))
			{
				setLastError("MsysAlloc失败");
				break;
			}
			m_allocMil = true;
		}

		if (!MdigAllocA(m_system, id, m_configFileName.toLocal8Bit().data(), M_DEFAULT, &m_digitizer))
		{
			setLastError("MdigAlloc失败");
			break;
		}

		MIL_INT miX = MdigInquire(m_digitizer, M_SIZE_X, M_NULL);
		MIL_INT miY = MdigInquire(m_digitizer, M_SIZE_Y, M_NULL);
		MIL_INT miBand = MdigInquire(m_digitizer, M_SIZE_BAND, M_NULL);
		MbufAllocColor(m_system, miBand, miX, miY, 8L + M_UNSIGNED, M_IMAGE + M_BASIC_BUFFER_PURPOSE, &m_image);
		MdigControl(m_digitizer, M_GRAB_MODE, M_SYNCHRONOUS);
		MdigControl(m_digitizer, M_CAMERA_LOCK, M_ENABLE);

		MdigControl(m_digitizer, M_GRAB_AUTOMATIC_INPUT_GAIN, M_DISABLE);
		MdigControl(m_digitizer, M_GRAB_INPUT_GAIN, 50);

		MappControl(M_ERROR, M_PRINT_DISABLE);

		MbufClear(m_image, 0);

		if (!m_digitizer)
		{
			setLastError("MilDigitizer失败");
			break;
		}

		MdigControl(m_digitizer, M_CAMERA_LOCK, M_DISABLE);
		MdigControl(m_digitizer, M_CHANNEL, m_channel[id]);
		MdigControl(m_digitizer, M_CAMERA_LOCK, M_ENABLE);
		MdigGrabContinuous(m_digitizer, m_image);
		m_open = true;
		result = true;
	} while (false);
	return result;
}

bool MilCap::close()
{
	stopCapture();

	if (m_digitizer)
	{
		MdigHalt(m_digitizer);
		//m_digitizer = M_NULL;
	}

	if (m_image)
	{
		MbufFree(m_image);
		//m_image = M_NULL;
	}

	if (m_digitizer)
	{
		MdigFree(m_digitizer);
		//m_digitizer = M_NULL;
	}

	return true;
}

void MilCap::run()
{
	while (!m_quit)
	{
		if (m_open && m_capture)
		{
			QMutexLocker locker(&m_mutex);
			MbufGetColor(m_image, M_PACKED + M_BGR24, M_ALL_BANDS, m_mat.data);
			MbufClear(m_image, 0);
			processImage();
		}
		msleep(m_interval);
	}
	quit();
}

bool MilCap::writeDcfFile()
{
	bool result = false;
	do
	{
		const QByteArray ntscData = "/Matrox Electronic Systems Ltd.\r\n"
			"/Copyright 1996.\r\n"
			"/\r\n"
			"/NTSC compatible DCF template.\r\n"
			"/\r\n"
			"/\r\n"
			"/\r\n"
			"/\r\n"
			"/\r\n"
			"/\r\n"
			"/\r\n"
			"/\r\n"
			"/\r\n"
			"/\r\n"
			"/\r\n"
			"/\r\n"
			"/\r\n"
			"/\r\n"
			"/\r\n"
			"/\r\n"
			"/\r\n"
			"/\r\n"
			"[CAMERA_NAME]\r\n"
			"NTSC compatible\r\n"
			"[CONFIG_FILE]\r\n"
			"50CF\r\n"
			"ORION\r\n"
			"Tue Jun 17 13:26:47 2008\r\n"
			"[INFO_FILE_REV]\r\n"
			"0009.0000.0000\r\n"
			"MORPHIS\r\n"
			"[GENERAL_PARAMETERS]\r\n"
			"GEN_MATCH_HW                                             0x1\r\n"
			"GEN_SAVED_W_ERR                                          0x0\r\n"
			"CT_LS                                                    0x0\r\n"
			"CT_FS                                                    0x1\r\n"
			"CT_CONV_INVERTED                                         0x0\r\n"
			"CT_TAPS                                                  0x0\r\n"
			"CT_CAMERA                                                0x0\r\n"
			"CT_BAYER_DISABLE                                         0x0\r\n"
			"CT_BAYER_BG                                              0x0\r\n"
			"CT_BAYER_GB                                              0x0\r\n"
			"CT_BAYER_GR                                              0x0\r\n"
			"CT_BAYER_RG                                              0x0\r\n"
			"VDC_DIG                                                  0x0\r\n"
			"VDC_ANA                                                  0x1\r\n"
			"VDC_MONO                                                 0x0\r\n"
			"VDC_C_COLOR                                              0x1\r\n"
			"VDC_RGB_COL                                              0x0\r\n"
			"VDC_RGB_PACK                                             0x0\r\n"
			"VDC_RGB_ALPHA                                            0x0\r\n"
			"VDC_SVID                                                 0x0\r\n"
			"VDC_YUVVID                                               0x0\r\n"
			"VDC_TTL                                                  0x0\r\n"
			"VDC_422                                                  0x0\r\n"
			"VDC_OPTO                                                 0x0\r\n"
			"VDC_LVDS                                                 0x0\r\n"
			"VDC_WD8                                                  0x1\r\n"
			"VDC_WD16                                                 0x0\r\n"
			"VDC_WD24                                                 0x0\r\n"
			"VDC_WD32                                                 0x0\r\n"
			"VDC_WD64                                                 0x0\r\n"
			"VDC_ALT_GRAB                                             0x0\r\n"
			"VDC_FROM_VCR                                             0x0\r\n"
			"VDC_IN_CH0                                               0x1\r\n"
			"VDC_IN_CH1                                               0x0\r\n"
			"VDC_IN_CH2                                               0x0\r\n"
			"VDC_IN_CH3                                               0x0\r\n"
			"VDC_IN_CH_C                                              0x0\r\n"
			"VDC_DIGITIZER                                            0x0\r\n"
			"VDC_PSG_MODE_1_CHECK                                     0x0\r\n"
			"VDC_PSG_MODE_2_CHECKS                                    0x0\r\n"
			"VDC_PSG_MODE_3_CHECKS                                    0x0\r\n"
			"VDC_PSG_MODE_4_CHECKS                                    0x0\r\n"
			"VDC_PSG_MODE_1_3_CHECKS                                  0x0\r\n"
			"VDC_PSG_MODE_ANY_CHECKS                                  0x0\r\n"
			"VDC_MIL_CHANNEL                                          0x0\r\n"
			"VDC_USE_PSG_0                                            0x0\r\n"
			"VDC_USE_PSG_1                                            0x0\r\n"
			"VDC_USE_PSG_2                                            0x0\r\n"
			"VDC_USE_PSG_3                                            0x0\r\n"
			"VDC_0_AC_WITH_DC                                         0x0\r\n"
			"VDC_0_DC_WITH_DC                                         0x0\r\n"
			"VDC_0_DC_WITHOUT_DC                                      0x0\r\n"
			"VDC_0_NO_FILTER                                          0x0\r\n"
			"VDC_0_FILTER_0                                           0x0\r\n"
			"VDC_0_FILTER_1                                           0x0\r\n"
			"VDC_1_AC_WITH_DC                                         0x0\r\n"
			"VDC_1_DC_WITH_DC                                         0x0\r\n"
			"VDC_1_DC_WITHOUT_DC                                      0x0\r\n"
			"VDC_1_NO_FILTER                                          0x0\r\n"
			"VDC_1_FILTER_0                                           0x0\r\n"
			"VDC_1_FILTER_1                                           0x0\r\n"
			"VDC_2_AC_WITH_DC                                         0x0\r\n"
			"VDC_2_DC_WITH_DC                                         0x0\r\n"
			"VDC_2_DC_WITHOUT_DC                                      0x0\r\n"
			"VDC_2_NO_FILTER                                          0x0\r\n"
			"VDC_2_FILTER_0                                           0x0\r\n"
			"VDC_2_FILTER_1                                           0x0\r\n"
			"VDC_3_AC_WITH_DC                                         0x0\r\n"
			"VDC_3_DC_WITH_DC                                         0x0\r\n"
			"VDC_3_DC_WITHOUT_DC                                      0x0\r\n"
			"VDC_3_NO_FILTER                                          0x0\r\n"
			"VDC_3_FILTER_0                                           0x0\r\n"
			"VDC_3_FILTER_1                                           0x0\r\n"
			"VDT_USE_HLOCK                                            0x0\r\n"
			"VDT_USE_VLOCK                                            0x0\r\n"
			"VDT_STD_170                                              0x0\r\n"
			"VDT_STD_330                                              0x0\r\n"
			"VDT_STD_CCIR                                             0x0\r\n"
			"VDT_STD_NTSC                                             0x1\r\n"
			"VDT_STD_PAL                                              0x0\r\n"
			"VDT_STD_CL                                               0x0\r\n"
			"VDT_STD_DIGITAL                                          0x0\r\n"
			"VDT_NOVERT                                               0x0\r\n"
			"VDT_HSYNC                                                0x3a\r\n"
			"VDT_HBPORCH                                              0x3c\r\n"
			"VDT_HFPORCH                                              0x16\r\n"
			"VDT_HACTIVE                                              0x280\r\n"
			"VDT_HTOTAL                                               0x30c\r\n"
			"VDT_HSYNC_FREQ                                           0x3d76\r\n"
			"VDT_VSYNC                                                0x6\r\n"
			"VDT_VBPORCH                                              0x21\r\n"
			"VDT_VFPORCH                                              0x6\r\n"
			"VDT_VACTIVE                                              0x1e0\r\n"
			"VDT_VTOTAL                                               0x20d\r\n"
			"VDT_VSYNC_FREQ                                           0x1d\r\n"
			"VDT_CL_IMAGE_SIZE_X                                      0x0\r\n"
			"VDT_CL_IMAGE_SIZE_Y                                      0x0\r\n"
			"VDT_CL_CROPPING_X                                        0x0\r\n"
			"VDT_CL_CROPPING_Y                                        0x0\r\n"
			"VDT_INTERL                                               0x1\r\n"
			"VDT_NINTRL                                               0x0\r\n"
			"VDT_SER                                                  0x0\r\n"
			"VDT_EQU                                                  0x0\r\n"
			"VDT_CLP_SYN                                              0x0\r\n"
			"VDT_CLP_BPO                                              0x1\r\n"
			"VDT_CLP_FPO                                              0x0\r\n"
			"PCK_CAM_GEN                                              0x0\r\n"
			"PCK_CAM_REC                                              0x0\r\n"
			"PCK_CAM_R&G                                              0x0\r\n"
			"PCK_OTH_REC                                              0x0\r\n"
			"PCK_USE_OUT                                              0x0\r\n"
			"PCK_CAM_XCHG                                             0x0\r\n"
			"PCK_ITTL                                                 0x0\r\n"
			"PCK_I422                                                 0x0\r\n"
			"PCK_IOPTO                                                0x0\r\n"
			"PCK_ILVDS                                                0x0\r\n"
			"PCK_IPOS                                                 0x0\r\n"
			"PCK_INEG                                                 0x0\r\n"
			"PCK_FREQ                                                 0xbb43d8\r\n"
			"PCK_INTDVED                                              0x0\r\n"
			"PCK_INTDIVF                                              0x0\r\n"
			"PCK_ODVED                                                0x0\r\n"
			"PCK_ODIVF                                                0x0\r\n"
			"PCK_OFREQDV                                              0xbb43d8\r\n"
			"PCK_OTTL                                                 0x0\r\n"
			"PCK_O422                                                 0x0\r\n"
			"PCK_OOPTO                                                0x0\r\n"
			"PCK_OLVDS                                                0x0\r\n"
			"PCK_OPOS                                                 0x0\r\n"
			"PCK_ONEG                                                 0x0\r\n"
			"PCK_IDELAY                                               0x0\r\n"
			"SYC_DIG                                                  0x0\r\n"
			"SYC_ANA                                                  0x1\r\n"
			"SYC_CAM_GEN                                              0x1\r\n"
			"SYC_CAM_R&G                                              0x0\r\n"
			"SYC_CAM_LATENCY                                          0x0\r\n"
			"SYC_MD_CSYN                                              0x1\r\n"
			"SYC_MD_HVSY                                              0x0\r\n"
			"SYC_MD_VSYN                                              0x0\r\n"
			"SYC_MD_HSYN                                              0x0\r\n"
			"SYC_EXT_VSY                                              0x0\r\n"
			"SYC_H_IN                                                 0x0\r\n"
			"SYC_H_OUT                                                0x0\r\n"
			"SYC_H_ITTL                                               0x0\r\n"
			"SYC_H_I422                                               0x0\r\n"
			"SYC_H_IOPTO                                              0x0\r\n"
			"SYC_H_ILVDS                                              0x0\r\n"
			"SYC_H_IPOS                                               0x0\r\n"
			"SYC_H_INEG                                               0x0\r\n"
			"SYC_H_OTTL                                               0x0\r\n"
			"SYC_H_O422                                               0x0\r\n"
			"SYC_H_OOPTO                                              0x0\r\n"
			"SYC_H_OLVDS                                              0x0\r\n"
			"SYC_H_OPOS                                               0x0\r\n"
			"SYC_H_ONEG                                               0x0\r\n"
			"SYC_V_IN                                                 0x0\r\n"
			"SYC_V_OUT                                                0x0\r\n"
			"SYC_V_ITTL                                               0x0\r\n"
			"SYC_V_I422                                               0x0\r\n"
			"SYC_V_IOPTO                                              0x0\r\n"
			"SYC_V_ILVDS                                              0x0\r\n"
			"SYC_V_IPOS                                               0x0\r\n"
			"SYC_V_INEG                                               0x0\r\n"
			"SYC_V_OTTL                                               0x0\r\n"
			"SYC_V_O422                                               0x0\r\n"
			"SYC_V_OOPTO                                              0x0\r\n"
			"SYC_V_OLVDS                                              0x0\r\n"
			"SYC_V_OPOS                                               0x0\r\n"
			"SYC_V_ONEG                                               0x0\r\n"
			"SYC_C_IN                                                 0x0\r\n"
			"SYC_C_OUT                                                0x0\r\n"
			"SYC_C_ITTL                                               0x0\r\n"
			"SYC_C_I422                                               0x0\r\n"
			"SYC_C_IOPTO                                              0x0\r\n"
			"SYC_C_ILVDS                                              0x0\r\n"
			"SYC_C_IPOS                                               0x0\r\n"
			"SYC_C_INEG                                               0x0\r\n"
			"SYC_C_OTTL                                               0x0\r\n"
			"SYC_C_O422                                               0x0\r\n"
			"SYC_C_OOPTO                                              0x0\r\n"
			"SYC_C_OLVDS                                              0x0\r\n"
			"SYC_C_OPOS                                               0x0\r\n"
			"SYC_C_ONEG                                               0x0\r\n"
			"SYC_BLK                                                  0x0\r\n"
			"SYC_COMP                                                 0x1\r\n"
			"SYC_SEP                                                  0x0\r\n"
			"SYC_IN_CH                                                0x0\r\n"
			"EXP_SYN_CLK                                              0x0\r\n"
			"EXP_ASY_CLK                                              0x0\r\n"
			"EXP_CLK_FREQ                                             0x0\r\n"
			"EXP_CLK_DVED                                             0x0\r\n"
			"EXP_CLK_DIVF                                             0x0\r\n"
			"EXP_MD_PERD                                              0x0\r\n"
			"EXP_MD_W_TRG                                             0x0\r\n"
			"EXP_MD_EXT                                               0x0\r\n"
			"EXP_MD_HSY                                               0x0\r\n"
			"EXP_MD_VSY                                               0x0\r\n"
			"EXP_MD_SW                                                0x0\r\n"
			"EXP_TRG_TTL                                              0x0\r\n"
			"EXP_TRG_422                                              0x0\r\n"
			"EXP_TRG_OPTO                                             0x0\r\n"
			"EXP_TRG_LVDS                                             0x0\r\n"
			"EXP_TRG_DEFAULT                                          0x0\r\n"
			"EXP_TRG_POS                                              0x0\r\n"
			"EXP_TRG_NEG                                              0x0\r\n"
			"EXP_OUT_DLYD                                             0x0\r\n"
			"EXP_OUT_T0                                               0x0\r\n"
			"EXP_OUT_T1                                               0x0\r\n"
			"EXP_OUT_T2                                               0x0\r\n"
			"EXP_OUT_T3                                               0x0\r\n"
			"EXP_OUT_TTL                                              0x0\r\n"
			"EXP_OUT_422                                              0x0\r\n"
			"EXP_OUT_OPTO                                             0x0\r\n"
			"EXP_OUT_LVDS                                             0x0\r\n"
			"EXP_OUT_DEFAULT                                          0x0\r\n"
			"EXP_OUT_POS                                              0x0\r\n"
			"EXP_OUT_NEG                                              0x0\r\n"
			"EXP_ARM_ENABLE                                           0x0\r\n"
			"EXP_ARM_DISABLE                                          0x0\r\n"
			"EXP_ARM_TTL                                              0x0\r\n"
			"EXP_ARM_422                                              0x0\r\n"
			"EXP_ARM_OPTO                                             0x0\r\n"
			"EXP_ARM_LVDS                                             0x0\r\n"
			"EXP_ARM_DEFAULT                                          0x0\r\n"
			"EXP_ARM_POS                                              0x0\r\n"
			"EXP_ARM_NEG                                              0x0\r\n"
			"GRB_MD_CONT                                              0x1\r\n"
			"GRB_MD_SW_TRG                                            0x0\r\n"
			"GRB_MD_HW_TRG                                            0x0\r\n"
			"GRB_START_ODD                                            0x0\r\n"
			"GRB_START_EVEN                                           0x0\r\n"
			"GRB_START_ANY                                            0x1\r\n"
			"GRB_ACT_NXT_FRM                                          0x0\r\n"
			"GRB_ACT_IMMEDIATE                                        0x0\r\n"
			"GRB_ACT_IMM_SKP_NFR                                      0x0\r\n"
			"GRB_TRG_TTL                                              0x0\r\n"
			"GRB_TRG_422                                              0x0\r\n"
			"GRB_TRG_OPTO                                             0x0\r\n"
			"GRB_TRG_LVDS                                             0x0\r\n"
			"GRB_TRG_DEFAULT                                          0x0\r\n"
			"GRB_TRG_POS                                              0x0\r\n"
			"GRB_TRG_NEG                                              0x0\r\n"
			"GRB_LS_FREE_RUN                                          0x0\r\n"
			"GRB_LS_FIXED_LINE                                        0x0\r\n"
			"GRB_LS_VARIABLE_LINE                                     0x0\r\n"
			"GRB_LS_FRMFIX_LINEFIX                                    0x0\r\n"
			"GRB_LS_FRMFIX_LINEVAR                                    0x0\r\n"
			"GRB_LS_FRMVAR_LINEFIX                                    0x0\r\n"
			"GRB_LS_FRMVAR_LINEVAR                                    0x0\r\n"
			"GRB_TRG_ARM_TTL                                          0x0\r\n"
			"GRB_TRG_ARM_422                                          0x0\r\n"
			"GRB_TRG_ARM_OPTO                                         0x0\r\n"
			"GRB_TRG_ARM_LVDS                                         0x0\r\n"
			"GRB_TRG_ARM_DEFAULT                                      0x0\r\n"
			"GRB_TRG_ARM_POS                                          0x0\r\n"
			"GRB_TRG_ARM_NEG                                          0x0\r\n"
			"VDL_USE_DEFVAL                                           0x1\r\n"
			"VDL_POS_SWG                                              0x1\r\n"
			"VDL_NEG_SWG                                              0x0\r\n"
			"VDL_BTH_SWG                                              0x0\r\n"
			"VDL_AMPL                                                 0x2bc\r\n"
			"VDL_PEDEST                                               0x0\r\n"
			"VDL_PED_AMP                                              0x32\r\n"
			"VDL_GAIN_IND                                             0x2\r\n"
			"VDL_GAIN                                                 0xaf0\r\n"
			"VDL_BRGHT                                                0x32\r\n"
			"VDL_CONTR                                                0x32\r\n"
			"VDL_SATUR                                                0x32\r\n"
			"VDL_HUE                                                  0x32\r\n"
			"DCF_IS_VIRTUAL                                           0x1\r\n"
			"DAT_INFOFILE_REV_MAJOR                                   0x9\r\n"
			"DAT_INFOFILE_REV_MINOR                                   0x0\r\n"
			"DAT_INFOFILE_REV_BUILD                                   0x0\r\n"
			"EXP_SYN_CLK_2                                            0x0\r\n"
			"EXP_ASY_CLK_2                                            0x0\r\n"
			"EXP_CLK_FREQ_2                                           0x0\r\n"
			"EXP_CLK_DVED_2                                           0x0\r\n"
			"EXP_CLK_DIVF_2                                           0x0\r\n"
			"EXP_MD_PERD_2                                            0x0\r\n"
			"EXP_MD_W_TRG_2                                           0x0\r\n"
			"EXP_MD_EXT_2                                             0x0\r\n"
			"EXP_MD_HSY_2                                             0x0\r\n"
			"EXP_MD_VSY_2                                             0x0\r\n"
			"EXP_MD_SW_2                                              0x0\r\n"
			"EXP_TRG_TTL_2                                            0x0\r\n"
			"EXP_TRG_422_2                                            0x0\r\n"
			"EXP_TRG_OPTO_2                                           0x0\r\n"
			"EXP_TRG_LVDS_2                                           0x0\r\n"
			"EXP_TRG_DEFAULT_2                                        0x0\r\n"
			"EXP_TRG_POS_2                                            0x0\r\n"
			"EXP_TRG_NEG_2                                            0x0\r\n"
			"EXP_OUT_DLYD_2                                           0x0\r\n"
			"EXP_OUT_T0_2                                             0x0\r\n"
			"EXP_OUT_T1_2                                             0x0\r\n"
			"EXP_OUT_T2_2                                             0x0\r\n"
			"EXP_OUT_T3_2                                             0x0\r\n"
			"EXP_OUT_TTL_2                                            0x0\r\n"
			"EXP_OUT_422_2                                            0x0\r\n"
			"EXP_OUT_OPTO_2                                           0x0\r\n"
			"EXP_OUT_LVDS_2                                           0x0\r\n"
			"EXP_OUT_DEFAULT_2                                        0x0\r\n"
			"EXP_OUT_POS_2                                            0x0\r\n"
			"EXP_OUT_NEG_2                                            0x0\r\n"
			"EXP_ARM_ENABLE_2                                         0x0\r\n"
			"EXP_ARM_DISABLE_2                                        0x0\r\n"
			"EXP_ARM_TTL_2                                            0x0\r\n"
			"EXP_ARM_422_2                                            0x0\r\n"
			"EXP_ARM_OPTO_2                                           0x0\r\n"
			"EXP_ARM_LVDS_2                                           0x0\r\n"
			"EXP_ARM_DEFAULT_2                                        0x0\r\n"
			"EXP_ARM_POS_2                                            0x0\r\n"
			"EXP_ARM_NEG_2                                            0x0\r\n"
			"GRB_RGB_PATH_FORCED                                      0x0\r\n"
			"GRB_TRG_SIGNAL_APORT                                     0x0\r\n"
			"GRB_TRG_SIGNAL_DPORT                                     0x0\r\n"
			"GRB_TRG_SIGNAL_HSDPORT                                   0x0\r\n"
			"GRB_TRG_SIGNAL_VSDPORT                                   0x0\r\n"
			"GRB_TRG_SIGNAL_TIMER1                                    0x0\r\n"
			"GRB_TRG_SIGNAL_TIMER2                                    0x0\r\n"
			"DEF_ORION                                                0x0\r\n"
			"DEF_4SIGHT                                               0x0\r\n"
			"DEF_MORPHIS                                              0x1\r\n"
			"DEF_INFO_INPUT                                           0x0\r\n"
			"DEF_DAC3502_DEFAULT                                      0x3b\r\n"
			"DEF_NTSC                                                 0x1\r\n"
			"DEF_PAL                                                  0x0\r\n"
			"DEF_HTOTAL_IN_NOTSTD                                     0x0\r\n"
			"DEF_HS_HBP_HFP_ZERO                                      0x0\r\n"
			"DEF_HCLMP_BORDER                                         0x12\r\n"
			"DEF_HCLMP_WIDTH                                          0x54\r\n"
			"DEF_HBPORCH                                              0x3c\r\n"
			"DEF_HCLMP_WIDTH_DEF                                      0x54\r\n"
			"DEF_HCLAMP_HBP_MIN                                       0x0\r\n"
			"DEF_HBPORCH_MAX                                          0x0\r\n"
			"DEF_HBPORCH_MIN                                          0x0\r\n"
			"DEF_HCLAMP_HBP_DEF_MIN                                   0x0\r\n"
			"DEF_HS1B                                                 0x44\r\n"
			"DEF_HS1E                                                 0x1fd\r\n"
			"DEF_MONO_VIA_RGB                                         0x0\r\n"
			"DEF_RGB_PATH                                             0x0\r\n"
			"DEF_MONO_VIA_DEC                                         0x0\r\n"
			"DEF_DEC_PATH                                             0x1\r\n"
			"DEF_MONO_CAM                                             0x0\r\n"
			"DEF_COLOR                                                0x1\r\n"
			"DEF_COLOR_CAM                                            0x1\r\n"
			"DEF_VIDEO_GAIN                                           0xaf0\r\n"
			"DEF_HAVB                                                 0x17\r\n"
			"DEF_HAVE                                                 0x13\r\n"
			"DEF_MORPHIS_NO_HCROP                                     0x0\r\n"
			"DEF_VACTIVE_ODD                                          0x0\r\n"
			"DEF_VTOTAL_IN_NOTSTD                                     0x0\r\n"
			"DEF_VS_VBP_VFP_ZERO                                      0x0\r\n"
			"DEF_VS_VBP_MIN                                           0x0\r\n"
			"DEF_VS_VBP_MAX                                           0x0\r\n"
			"DEF_ORION_VIN_HIGH                                       0x0\r\n"
			"DEF_VBI                                                  0x3\r\n"
			"[REG_DIGIT]\r\n"
			"INFO_XSIZE                                               0x280\r\n"
			"INFO_YSIZE                                               0x1e0\r\n"
			"INFO_MODE                                                0x4\r\n"
			"INFO_TYPE                                                0x2\r\n"
			"INFO_DEPTH                                               0x8\r\n"
			"INFO_BAND                                                0x3\r\n"
			"INFO_INPUT                                               0x0\r\n"
			"INFO_PIXCLK                                              0xbb43d8\r\n"
			"INFO_PIPELINE                                            0x0\r\n"
			"INFO_MODULE_422                                          0x0\r\n"
			"INFO_CHANNEL                                             0x0\r\n"
			"AD5302_DAC_A                                             0x3b\r\n"
			"AD5302_DAC_B                                             0x3b\r\n"
			"AD5302_DAC_C                                             0x3b\r\n"
			"AD5302_DAC_E                                             0x3b\r\n"
			"AD5302_DAC_F                                             0x3b\r\n"
			"AD5302_DAC_G                                             0x3b\r\n"
			"KS0127_STAT                                              0x0\r\n"
			"KS0127_CMDA                                              0x3\r\n"
			"KS0127_CMDB                                              0x42\r\n"
			"KS0127_CMDC                                              0x2\r\n"
			"KS0127_CMDD                                              0x0\r\n"
			"KS0127_HAVB                                              0x17\r\n"
			"KS0127_HAVE                                              0x13\r\n"
			"KS0127_HS1B                                              0x22\r\n"
			"KS0127_HS1E                                              0xfe\r\n"
			"KS0127_HS2B                                              0x0\r\n"
			"KS0127_HS2E                                              0x0\r\n"
			"KS0127_AGC                                               0x4f\r\n"
			"KS0127_HXTRA                                             0x0\r\n"
			"KS0127_CDEM                                              0x0\r\n"
			"KS0127_PORTAB                                            0xf\r\n"
			"KS0127_LUMA                                              0x10\r\n"
			"KS0127_CON                                               0x0\r\n"
			"KS0127_BRT                                               0x0\r\n"
			"KS0127_CHROMA                                            0x0\r\n"
			"KS0127_CHROMB                                            0x0\r\n"
			"KS0127_DEMOD                                             0x82\r\n"
			"KS0127_SAT                                               0x0\r\n"
			"KS0127_HUE                                               0x0\r\n"
			"KS0127_VERTIA                                            0xa0\r\n"
			"KS0127_VERTIB                                            0x2\r\n"
			"KS0127_VERTIC                                            0x83\r\n"
			"KS0127_HSCLL                                             0x1\r\n"
			"KS0127_HSCLH                                             0x0\r\n"
			"KS0127_VSCLL                                             0x0\r\n"
			"KS0127_VSCLH                                             0x0\r\n"
			"KS0127_OFMTA                                             0x30\r\n"
			"KS0127_OFMTB                                             0x70\r\n"
			"KS0127_VBICTL                                            0x0\r\n"
			"KS0127_VBIL30                                            0x0\r\n"
			"KS0127_VBIL74                                            0x0\r\n"
			"KS0127_VBIL118                                           0x0\r\n"
			"KS0127_VBIL1512                                          0x0\r\n"
			"KS0127_TTFRAM                                            0x0\r\n"
			"KS0127_UVOFFL                                            0x0\r\n"
			"KS0127_UVOFFH                                            0x0\r\n"
			"KS0127_UGAIN                                             0x0\r\n"
			"KS0127_VGAIN                                             0x0\r\n"
			"KS0127_VAVB                                              0xc\r\n"
			"KS0127_VAVE                                              0x81\r\n"
			"KS0127_CTRACK                                            0x0\r\n"
			"KS0127_POLCTL                                            0x80\r\n"
			"KS0127_REFCOD                                            0xa4\r\n"
			"KS0127_INVALY                                            0x0\r\n"
			"KS0127_INVALU                                            0x0\r\n"
			"KS0127_INVALV                                            0x0\r\n"
			"KS0127_UNUSEY                                            0x0\r\n"
			"KS0127_UNUSEU                                            0x0\r\n"
			"KS0127_UNUSEV                                            0x0\r\n"
			"KS0127_EXCTRL                                            0x8\r\n"
			"KS0127_TRACKA                                            0x0\r\n"
			"KS0127_SHS1A                                             0x0\r\n"
			"KS0127_TRACKB                                            0x80\r\n"
			"KS0127_RTC                                               0x0\r\n"
			"KS0127_CMDE                                              0x9\r\n"
			"KS0127_VSDEL                                             0x0\r\n"
			"KS0127_CMDF                                              0x26\r\n"
			"ADV7185_INPUTCTL                                         0x50\r\n"
			"ADV7185_VIDEOSEL                                         0x8c\r\n"
			"ADV7185_VIDEOENCTL                                       0x4\r\n"
			"ADV7185_OUTPUTCTL                                        0xc\r\n"
			"ADV7185_EXTOUTCTL                                        0x8d\r\n"
			"ADV7185_GENPURPOUT                                       0xf0\r\n"
			"ADV7185_FIFOCTL                                          0x8\r\n"
			"ADV7185_CONTCTL                                          0x80\r\n"
			"ADV7185_SATCTL                                           0x80\r\n"
			"ADV7185_BRIGHTCTL                                        0x0\r\n"
			"ADV7185_HUECTL                                           0x0\r\n"
			"ADV7185_DEFVALY                                          0x10\r\n"
			"ADV7185_DEFVALC                                          0x18\r\n"
			"ADV7185_TEMPDEC                                          0x0\r\n"
			"ADV7185_POWERMAN                                         0x0\r\n"
			"ADV7185_ANACLCTL                                         0x10\r\n"
			"ADV7185_DIGCLCTL1                                        0x60\r\n"
			"ADV7185_DIGCLCTL2                                        0x0\r\n"
			"ADV7185_SHAPFILCTL                                       0xdb\r\n"
			"ADV7185_MISCCTL                                          0x4\r\n"
			"ADV7185_SCACROMSB                                        0x11\r\n"
			"ADV7185_ACTVIDDESLINES                                   0xf3\r\n"
			"ADV7185_ACTVIDVERTBEG                                    0x1f\r\n"
			"ADV7185_VERTSCALEVAL1                                    0x1\r\n"
			"ADV7185_VERTSCALEVAL2                                    0x0\r\n"
			"ADV7185_ACTVIDHORBEG                                     0x43\r\n"
			"ADV7185_ACTVIDDESPIX                                     0x80\r\n"
			"ADV7185_HORSCALEVAL1                                     0xa\r\n"
			"ADV7185_HORSCALEVAL2                                     0x81\r\n"
			"ADV7185_COLSUBCARCTL1                                    0xe0\r\n"
			"ADV7185_COLSUBCARCTL2                                    0x0\r\n"
			"ADV7185_COLSUBCARCTL3                                    0x0\r\n"
			"ADV7185_COLSUBCARCTL4                                    0x0\r\n"
			"ADV7185_PIXDELAYCTL                                      0x60\r\n"
			"ADV7185_MANCLKCTL1                                       0x0\r\n"
			"ADV7185_MANCLKCTL2                                       0x0\r\n"
			"ADV7185_MANCLKCTL3                                       0x0\r\n"
			"ADV7185_AUTOCLKCTL                                       0xa0\r\n"
			"ADV7185_AGCMODECTL                                       0xae\r\n"
			"ADV7185_CHROGAINCTL1                                     0x78\r\n"
			"ADV7185_CHROGAINCTL2                                     0x0\r\n"
			"ADV7185_LUMAGAINCTL1                                     0x7a\r\n"
			"ADV7185_LUMAGAINCTL2                                     0x0\r\n"
			"ADV7185_MANGAINSHADCTL1                                  0x70\r\n"
			"ADV7185_MANGAINSHADCTL2                                  0x0\r\n"
			"ADV7185_MISCGAINCTL                                      0xe2\r\n"
			"ADV7185_HSYNCPOSCTL1                                     0xf\r\n"
			"ADV7185_HSYNCPOSCTL2                                     0x0\r\n"
			"ADV7185_HSYNCPOSCTL3                                     0x3a\r\n"
			"ADV7185_POLARITYCTL                                      0xa0\r\n"
			"ADV7185_CHROMACOMBFILTER                                 0x3b\r\n"
			"ADV7183A_SHAPFILCTL2                                     0x93\r\n"
			"ADV7183A_NTSCCOMBCTL                                     0x80\r\n"
			"ADV7183A_PALCOMBCTL                                      0xc0\r\n"
			"ADV7183A_MANWINDOWCTL                                    0x43\r\n"
			"ADV7183A_CTIDNRCTL1                                      0xef\r\n"
			"ADV7183A_CTIDNRCTL2                                      0x8\r\n"
			"ADV7183A_CTIDNRCTL4                                      0x8\r\n"
			"ADV7183A_LOCKCOUNT                                       0x64\r\n"
			"PIXFORMATTER_CONFIG1                                     0x6\r\n"
			"PIXFORMATTER_CONFIG2                                     0x24\r\n"
			"PIXFORMATTER_CONFIG3                                     0x1\r\n"
			"PIXFORMATTER_FGCTL1                                      0x0\r\n"
			"PIXFORMATTER_FGCTL2                                      0x0\r\n"
			"PIXFORMATTER_USEROUT                                     0x0\r\n"
			"PIXFORMATTER_USERIN                                      0x0\r\n"
			"PIXFORMATTER_GBCTL                                       0x0\r\n"
			"PIXFORMATTER_TGRCTL                                      0x10\r\n"
			"PIXFORMATTER_INTSTAT                                     0x0\r\n"
			"PIXFORMATTER_INTMASK                                     0x0\r\n"
			"PIXFORMATTER_INTOEN                                      0x0\r\n"
			"PIXFORMATTER_DECCTRL                                     0x68\r\n"
			"PIXFORMATTER_HSTARTLOW                                   0x7e\r\n"
			"PIXFORMATTER_HSTARTHIGH                                  0x0\r\n"
			"PIXFORMATTER_HSTOPLOW                                    0x2\r\n"
			"PIXFORMATTER_HSTOPHIGH                                   0x3\r\n"
			"PIXFORMATTER_VSTARTLOW                                   0xc\r\n"
			"PIXFORMATTER_VSTARTHIGH                                  0x0\r\n"
			"PIXFORMATTER_VSTOPLOW                                    0xfc\r\n"
			"PIXFORMATTER_VSTOPHIGH                                   0x0\r\n"
			"IDRE_VALIDGEN                                            0x1400f0\r\n"
			"TOUCAN_VINHEIGHT                                         0xf0\r\n"
			"TOUCAN_VBICOUNT                                          0x160017\r\n"
			"TOUCAN_VBICOUNT_STD                                      0x30003\r\n"
			"TOUCAN_VBICOUNT_RGB                                      0x30003\r\n"
			"TOUCAN_VBICOUNT_DUAL                                     0x30003\r\n"
			"[REG_MODIF_STATE]\r\n"
			"INFO_XSIZE                                             not_modified\r\n"
			"INFO_YSIZE                                             not_modified\r\n"
			"INFO_MODE                                              not_modified\r\n"
			"INFO_TYPE                                              not_modified\r\n"
			"INFO_DEPTH                                             not_modified\r\n"
			"INFO_BAND                                              not_modified\r\n"
			"INFO_INPUT                                             not_modified\r\n"
			"INFO_PIXCLK                                            not_modified\r\n"
			"INFO_PIPELINE                                          not_modified\r\n"
			"INFO_MODULE_422                                        not_modified\r\n"
			"INFO_CHANNEL                                           not_modified\r\n"
			"AD5302_DAC_A                                           not_modified\r\n"
			"AD5302_DAC_B                                           not_modified\r\n"
			"AD5302_DAC_C                                           not_modified\r\n"
			"AD5302_DAC_E                                           not_modified\r\n"
			"AD5302_DAC_F                                           not_modified\r\n"
			"AD5302_DAC_G                                           not_modified\r\n"
			"KS0127_STAT                                            not_modified\r\n"
			"KS0127_CMDA                                            not_modified\r\n"
			"KS0127_CMDB                                            not_modified\r\n"
			"KS0127_CMDC                                            not_modified\r\n"
			"KS0127_CMDD                                            not_modified\r\n"
			"KS0127_HAVB                                            not_modified\r\n"
			"KS0127_HAVE                                            not_modified\r\n"
			"KS0127_HS1B                                            not_modified\r\n"
			"KS0127_HS1E                                            not_modified\r\n"
			"KS0127_HS2B                                            not_modified\r\n"
			"KS0127_HS2E                                            not_modified\r\n"
			"KS0127_AGC                                             not_modified\r\n"
			"KS0127_HXTRA                                           not_modified\r\n"
			"KS0127_CDEM                                            not_modified\r\n"
			"KS0127_PORTAB                                          not_modified\r\n"
			"KS0127_LUMA                                            not_modified\r\n"
			"KS0127_CON                                             not_modified\r\n"
			"KS0127_BRT                                             not_modified\r\n"
			"KS0127_CHROMA                                          not_modified\r\n"
			"KS0127_CHROMB                                          not_modified\r\n"
			"KS0127_DEMOD                                           not_modified\r\n"
			"KS0127_SAT                                             not_modified\r\n"
			"KS0127_HUE                                             not_modified\r\n"
			"KS0127_VERTIA                                          not_modified\r\n"
			"KS0127_VERTIB                                          not_modified\r\n"
			"KS0127_VERTIC                                          not_modified\r\n"
			"KS0127_HSCLL                                           not_modified\r\n"
			"KS0127_HSCLH                                           not_modified\r\n"
			"KS0127_VSCLL                                           not_modified\r\n"
			"KS0127_VSCLH                                           not_modified\r\n"
			"KS0127_OFMTA                                           not_modified\r\n"
			"KS0127_OFMTB                                           not_modified\r\n"
			"KS0127_VBICTL                                          not_modified\r\n"
			"KS0127_VBIL30                                          not_modified\r\n"
			"KS0127_VBIL74                                          not_modified\r\n"
			"KS0127_VBIL118                                         not_modified\r\n"
			"KS0127_VBIL1512                                        not_modified\r\n"
			"KS0127_TTFRAM                                          not_modified\r\n"
			"KS0127_UVOFFL                                          not_modified\r\n"
			"KS0127_UVOFFH                                          not_modified\r\n"
			"KS0127_UGAIN                                           not_modified\r\n"
			"KS0127_VGAIN                                           not_modified\r\n"
			"KS0127_VAVB                                            not_modified\r\n"
			"KS0127_VAVE                                            not_modified\r\n"
			"KS0127_CTRACK                                          not_modified\r\n"
			"KS0127_POLCTL                                          not_modified\r\n"
			"KS0127_REFCOD                                          not_modified\r\n"
			"KS0127_INVALY                                          not_modified\r\n"
			"KS0127_INVALU                                          not_modified\r\n"
			"KS0127_INVALV                                          not_modified\r\n"
			"KS0127_UNUSEY                                          not_modified\r\n"
			"KS0127_UNUSEU                                          not_modified\r\n"
			"KS0127_UNUSEV                                          not_modified\r\n"
			"KS0127_EXCTRL                                          not_modified\r\n"
			"KS0127_TRACKA                                          not_modified\r\n"
			"KS0127_SHS1A                                           not_modified\r\n"
			"KS0127_TRACKB                                          not_modified\r\n"
			"KS0127_RTC                                             not_modified\r\n"
			"KS0127_CMDE                                            not_modified\r\n"
			"KS0127_VSDEL                                           not_modified\r\n"
			"KS0127_CMDF                                            not_modified\r\n"
			"ADV7185_INPUTCTL                                       not_modified\r\n"
			"ADV7185_VIDEOSEL                                       not_modified\r\n"
			"ADV7185_VIDEOENCTL                                     not_modified\r\n"
			"ADV7185_OUTPUTCTL                                      not_modified\r\n"
			"ADV7185_EXTOUTCTL                                      not_modified\r\n"
			"ADV7185_GENPURPOUT                                     not_modified\r\n"
			"ADV7185_FIFOCTL                                        not_modified\r\n"
			"ADV7185_CONTCTL                                        not_modified\r\n"
			"ADV7185_SATCTL                                         not_modified\r\n"
			"ADV7185_BRIGHTCTL                                      not_modified\r\n"
			"ADV7185_HUECTL                                         not_modified\r\n"
			"ADV7185_DEFVALY                                        not_modified\r\n"
			"ADV7185_DEFVALC                                        not_modified\r\n"
			"ADV7185_TEMPDEC                                        not_modified\r\n"
			"ADV7185_POWERMAN                                       not_modified\r\n"
			"ADV7185_ANACLCTL                                       not_modified\r\n"
			"ADV7185_DIGCLCTL1                                      not_modified\r\n"
			"ADV7185_DIGCLCTL2                                      not_modified\r\n"
			"ADV7185_SHAPFILCTL                                     not_modified\r\n"
			"ADV7185_MISCCTL                                        not_modified\r\n"
			"ADV7185_SCACROMSB                                      not_modified\r\n"
			"ADV7185_ACTVIDDESLINES                                 not_modified\r\n"
			"ADV7185_ACTVIDVERTBEG                                  not_modified\r\n"
			"ADV7185_VERTSCALEVAL1                                  not_modified\r\n"
			"ADV7185_VERTSCALEVAL2                                  not_modified\r\n"
			"ADV7185_ACTVIDHORBEG                                   not_modified\r\n"
			"ADV7185_ACTVIDDESPIX                                   not_modified\r\n"
			"ADV7185_HORSCALEVAL1                                   not_modified\r\n"
			"ADV7185_HORSCALEVAL2                                   not_modified\r\n"
			"ADV7185_COLSUBCARCTL1                                  not_modified\r\n"
			"ADV7185_COLSUBCARCTL2                                  not_modified\r\n"
			"ADV7185_COLSUBCARCTL3                                  not_modified\r\n"
			"ADV7185_COLSUBCARCTL4                                  not_modified\r\n"
			"ADV7185_PIXDELAYCTL                                    not_modified\r\n"
			"ADV7185_MANCLKCTL1                                     not_modified\r\n"
			"ADV7185_MANCLKCTL2                                     not_modified\r\n"
			"ADV7185_MANCLKCTL3                                     not_modified\r\n"
			"ADV7185_AUTOCLKCTL                                     not_modified\r\n"
			"ADV7185_AGCMODECTL                                     not_modified\r\n"
			"ADV7185_CHROGAINCTL1                                   not_modified\r\n"
			"ADV7185_CHROGAINCTL2                                   not_modified\r\n"
			"ADV7185_LUMAGAINCTL1                                   not_modified\r\n"
			"ADV7185_LUMAGAINCTL2                                   not_modified\r\n"
			"ADV7185_MANGAINSHADCTL1                                not_modified\r\n"
			"ADV7185_MANGAINSHADCTL2                                not_modified\r\n"
			"ADV7185_MISCGAINCTL                                    not_modified\r\n"
			"ADV7185_HSYNCPOSCTL1                                   not_modified\r\n"
			"ADV7185_HSYNCPOSCTL2                                   not_modified\r\n"
			"ADV7185_HSYNCPOSCTL3                                   not_modified\r\n"
			"ADV7185_POLARITYCTL                                    not_modified\r\n"
			"ADV7185_CHROMACOMBFILTER                               not_modified\r\n"
			"ADV7183A_SHAPFILCTL2                                   not_modified\r\n"
			"ADV7183A_NTSCCOMBCTL                                   not_modified\r\n"
			"ADV7183A_PALCOMBCTL                                    not_modified\r\n"
			"ADV7183A_MANWINDOWCTL                                  not_modified\r\n"
			"ADV7183A_CTIDNRCTL1                                    not_modified\r\n"
			"ADV7183A_CTIDNRCTL2                                    not_modified\r\n"
			"ADV7183A_CTIDNRCTL4                                    not_modified\r\n"
			"ADV7183A_LOCKCOUNT                                     not_modified\r\n"
			"PIXFORMATTER_CONFIG1                                   not_modified\r\n"
			"PIXFORMATTER_CONFIG2                                   not_modified\r\n"
			"PIXFORMATTER_CONFIG3                                   not_modified\r\n"
			"PIXFORMATTER_FGCTL1                                    not_modified\r\n"
			"PIXFORMATTER_FGCTL2                                    not_modified\r\n"
			"PIXFORMATTER_USEROUT                                   not_modified\r\n"
			"PIXFORMATTER_USERIN                                    not_modified\r\n"
			"PIXFORMATTER_GBCTL                                     not_modified\r\n"
			"PIXFORMATTER_TGRCTL                                    not_modified\r\n"
			"PIXFORMATTER_INTSTAT                                   not_modified\r\n"
			"PIXFORMATTER_INTMASK                                   not_modified\r\n"
			"PIXFORMATTER_INTOEN                                    not_modified\r\n"
			"PIXFORMATTER_DECCTRL                                   not_modified\r\n"
			"PIXFORMATTER_HSTARTLOW                                 not_modified\r\n"
			"PIXFORMATTER_HSTARTHIGH                                not_modified\r\n"
			"PIXFORMATTER_HSTOPLOW                                  not_modified\r\n"
			"PIXFORMATTER_HSTOPHIGH                                 not_modified\r\n"
			"PIXFORMATTER_VSTARTLOW                                 not_modified\r\n"
			"PIXFORMATTER_VSTARTHIGH                                not_modified\r\n"
			"PIXFORMATTER_VSTOPLOW                                  not_modified\r\n"
			"PIXFORMATTER_VSTOPHIGH                                 not_modified\r\n"
			"IDRE_VALIDGEN                                          not_modified\r\n"
			"TOUCAN_VINHEIGHT                                       not_modified\r\n"
			"TOUCAN_VBICOUNT                                        not_modified\r\n"
			"TOUCAN_VBICOUNT_STD                                    not_modified\r\n"
			"TOUCAN_VBICOUNT_RGB                                    not_modified\r\n"
			"TOUCAN_VBICOUNT_DUAL                                   not_modified\r\n"
			"[EOF]\r\n"
			"FILE_SIZE                                                0xabf8\r\n"
			"FILE_CRC                                                 0xed913647";

		if (!generateConfigFileName("ntsc.dcf"))
		{
			break;
		}

		if (QFileInfo(m_configFileName).exists())
		{
			result = true;
			break;
		}

		QFile file(m_configFileName);
		if (!file.open(QFile::WriteOnly))
		{
			setLastError(file.errorString());
			break;
		}

		if (file.write(ntscData) != ntscData.size())
		{
			setLastError("写入数据长度校验失败");
			break;
		}
		file.close();
		result = true;
	} while (false);
	return result;
}


//ImageProcess.h
#pragma once
#pragma execution_character_set("utf-8")

//这里是你的OpenCv头文件路径

#include <OpenCv/OpenCv.h>
#include <QString>
#include <QImage>
#include <QPixmap>
#include <QMutex>

/*
* @brief,图像处理类库
*/
class ImageProcess
{
public:
	/*
	* @brief,构造
	*/
	ImageProcess();

	/*
	* @brief,析构
	*/
	~ImageProcess();

	/*
	* @brief,yuv422转bgr
	* @param1,yuv数据
	* @param2,yuv宽度
	* @param3,yuv高度
	* @param4,bgr数据
	* @notice,bgr数据,必须满足条件>=yuvWidth * yuvHeight * 3
	* @return,void
	*/
	static void yuv422ToBgr(const uchar* yuvData, int yuvWidth, int yuvHeight, uchar* bgrData);

	/*
	* @brief,yuv444转bgr
	* @param1,yuv数据
	* @param2,yuv宽度
	* @param3,yuv高度
	* @param4,bgr数据
	* @notice,bgr数据,必须满足条件>=yuvWidth * yuvHeight * 3
	* @return,void
	*/
	static void yuv444ToBgr(const uchar* yuvData, int yuvWidth, int yuvHeight, uchar* bgrData);

	/*
	* @brief,bgrToYuv422
	* @param1,bgr数据
	* @param2,bgr宽度
	* @param3,bgr高度
	* @param4,yuv数据
	* @return,void
	*/
	static void bgrToYuv422(const uchar* bgrData, int bgrWidth, int bgrHeight, uchar* yuvData);

	/*
	* @brief,rgb转bgr
	* @param1,数据
	* @param2,宽度
	* @param3,高度
	* @return,void
	*/
	static void rgbToBgr(uchar* data, int width, int height);

	/*
	* @brief,rgb转bgr
	* @param1,原始数据
	* @param2,原始宽度
	* @param3,原始高度
	* @param4,目标数据
	* @return,void
	*/
	static void rgbToBgr(const uchar* src, int width, int height, uchar* dst);

	/*
	* @brief,bgr转rgb
	* @param1,数据
	* @param2,宽度
	* @param3,高度
	* @return,void
	*/
	static void bgrToRgb(uchar* data, int width, int height);

	/*
	* @brief,bgr转rgb
	* @param1,原始数据
	* @param2,原始宽度
	* @param3,原始高度
	* @param4,目标数据
	* @return,void
	*/
	static void bgrToRgb(const uchar* src, int width, int height, uchar* dst);

	/*
	* @brief,cv::Mat转QImage
	* @param1,图像源
	* @return,QImage
	*/
	static QImage cvMatToQImage(const cv::Mat& mat, const cv::Size& resize = cv::Size(), QImage::Format fmt = QImage::Format_RGB888);

	/*
	* @brief,cv::Mat转QPixmap
	* @param1,图像源
	* @return,QPixmap
	*/
	static QPixmap cvMatToQPixmap(const cv::Mat& mat, const cv::Size& resize = cv::Size(), QImage::Format fmt = QImage::Format_RGB888);

	/*
	* @brief,拜尔8RG转BGR
	* @notice,Bayer8简称Raw8这两个相同.
	* @param1,原始数据
	* @param2,原始宽度
	* @param3,原始高度
	* @param4,目标数据
	* @return,void
	*/
	static void bayer8RgToBgr(const uchar* src, int width, int height, uchar* dst);

	/*
	* @brief,拜尔10RG转BGR
	* @param1,原始数据
	* @param2,原始宽度
	* @param3,原始高度
	* @param4,目标数据
	* @return,void
	*/
	static void bayer10RgToBgr(const uchar* src, int width, int height, uchar* dst);

	/*
	* @brief,拜尔12RG转BGR
	* @param1,原始数据
	* @param2,原始宽度
	* @param3,原始高度
	* @param4,目标数据
	* @return,void
	*/
	static void bayer12RgToBgr(const uchar* src, int width, int height, uchar* dst);

	/*
	* @brief,拜尔8BG转BGR
	* @param1,原始数据
	* @param2,原始宽度
	* @param3,原始高度
	* @param4,目标数据
	* @return,void
	*/
	static void bayer8BgToBgr(const uchar* src, int width, int height, uchar* dst);

	/*
	* @brief,拜尔10BG转BGR
	* @param1,原始数据
	* @param2,原始宽度
	* @param3,原始高度
	* @param4,目标数据
	* @return,void
	*/
	static void bayer10BgToBgr(const uchar* src, int width, int height, uchar* dst);

	/*
	* @brief,拜尔12BG转BGR
	* @param1,原始数据
	* @param2,原始宽度
	* @param3,原始高度
	* @param4,目标数据
	* @return,void
	*/
	static void bayer12BgToBgr(const uchar* src, int width, int height, uchar* dst);

	/*
	* @brief,拜尔8GB转BGR
	* @param1,原始数据
	* @param2,原始宽度
	* @param3,原始高度
	* @param4,目标数据
	* @return,void
	*/
	static void bayer8GbToBgr(const uchar* src, int width, int height, uchar* dst);

	/*
	* @brief,拜尔10GB转BGR
	* @param1,原始数据
	* @param2,原始宽度
	* @param3,原始高度
	* @param4,目标数据
	* @return,void
	*/
	static void bayer10GbToBgr(const uchar* src, int width, int height, uchar* dst);

	/*
	* @brief,拜尔12GB转BGR
	* @param1,原始数据
	* @param2,原始宽度
	* @param3,原始高度
	* @param4,目标数据
	* @return,void
	*/
	static void bayer12GbToBgr(const uchar* src, int width, int height, uchar* dst);

	/*
	* @brief,拜尔8GR转BGR
	* @param1,原始数据
	* @param2,原始宽度
	* @param3,原始高度
	* @param4,目标数据
	* @return,void
	*/
	static void bayer8GrToBgr(const uchar* src, int width, int height, uchar* dst);

	/*
	* @brief,拜尔GR10转BGR
	* @param1,原始数据
	* @param2,原始宽度
	* @param3,原始高度
	* @param4,目标数据
	* @return,void
	*/
	static void bayer10GrToBgr(const uchar* src, int width, int height, uchar* dst);

	/*
	* @brief,拜尔GR12转BGR
	* @param1,原始数据
	* @param2,原始宽度
	* @param3,原始高度
	* @param4,目标数据
	* @return,void
	*/
	static void bayer12GrToBgr(const uchar* src, int width, int height, uchar* dst);

	/*
	* @brief,设置文本字体
	* @param1,字体名称
	* @param2,字体索引
	* @return,void
	*/
	static void setTextFont(const QString& fontName, int id = 0);

	/*
	* @brief,输出文本(支持中文)
	* @param1,图像
	* @param2,文本
	* @param3,坐标
	* @param4,字体高度
	* @param5,颜色
	* @param6,粗细
	* @param7,线类型
	* @param8,左下原点
	* @return,void
	*/
	static void putText(cv::InputOutputArray img, const QString& text,
		cv::Point org, int fontHeight, cv::Scalar color = CV_RGB(255, 0, 0),
		int thickness = -1, cv::LineTypes lineType = cv::LineTypes::LINE_8,
		bool bottomLeftOrigin = true);

	/*
	* @brief,获取文本大小(支持中文)
	* @param1,文本
	* @param2,字体高度
	* @param3,粗细
	* @param4,基线
	* @return,cv::Size
	*/
	static cv::Size getTextSize(const QString& text, int fontHeight, int thickness = -1, int* baseLine = nullptr);

	/*
	* @brief,获取中心点(中文可能不准确)
	* @param1,图像大小
	* @param2,文本
	* @param3,字体高度
	* @param4,粗细
	* @return,cv::Point
	*/
	static cv::Point getCenterPoint(cv::Size imgSize, const QString& text,
		int fontHeight, int thickness = -1);

	/*
	* @brief,输出文本在图像中心(中文可能不准确)
	* @param1,图像
	* @param2,文本
	* @param3,字体高度
	* @param4,颜色
	* @param5,修复误差
	* @param6,粗细
	* @return,void
	*/
	static void putTextOnCenter(cv::Mat& img, const QString& text,
		int fontHeight, cv::Scalar color = CV_RGB(255, 0, 0),
		cv::Point repair = cv::Point(0, 0),
		int thickness = -1);

	/*
	* @brief,获取每秒帧数
	* @return,int
	*/
	static int getFps();

	/*
	* @brief,打印FPS到图像上
	* @param1,字体大小
	* @param2,字体颜色
	* @param3,坐标点
	* @param4,字体粗细
	* @return,void
	*/
	static void putFps(cv::Mat& img, double fontScale = 2, int thickness = 2,
		const cv::Scalar& color = CV_RGB(0, 255, 0),
		cv::Point point = cv::Point(-1, -1));
private:
	static cv::Ptr<cv::freetype::FreeType2> createFreeType2();
private:
	static cv::Ptr<cv::freetype::FreeType2> m_ft2Data;

	static QMutex m_ft2Lock;
};
//ImageProcess.cpp
#include "ImageProcess.h"
#include <Windows.h>

cv::Ptr<cv::freetype::FreeType2> ImageProcess::m_ft2Data(ImageProcess::createFreeType2());

QMutex ImageProcess::m_ft2Lock;

#define _YUV_GET_R(Y,U,V) (Y + (180 * (V - 128) >> 7))

#define _YUV_GET_G(Y,U,V) (Y - (44 * (U - 128) >> 7) - (92 * (V - 128) >> 7))

#define _YUV_GET_B(Y,U,V) (Y + (228 * (U - 128) >> 7))

#define _BGR_GET_Y(B,G,R) ((38 * (R) >> 7 ) + (75 * (G) >>  7) + (15 * (B) >> 7) )

#define _BGR_GET_U(B0,G0,R0,B1,G1,R1) ((( 56 * ((B0)+(B1)) >> 7) - ( 19 * ((R0) + (R1)) >> 7) - ( 37 * ((G0) + (G1)) >>7)) / 2 + 128)

#define _BGR_GET_V(B0,G0,R0,B1,G1,R1) ((( 79 * ((R0)+(R1)) >> 7) - ( 66 * ((G0) + (G1)) >> 7) - ( 13 * ((B0) + (B1)) >>7)) / 2 + 128)

ImageProcess::ImageProcess()
{

}

ImageProcess::~ImageProcess()
{

}

void ImageProcess::yuv422ToBgr(const uchar* yuvData, int yuvWidth, int yuvHeight, uchar* bgrData)
{
	if (!yuvData || yuvWidth <= 0 || yuvHeight <= 0 || !bgrData)
	{
		return;
	}

	const int yuvSize = yuvWidth * yuvHeight;
	const uchar* src = yuvData;
	uchar* dst = bgrData;

	for (int i = 0; i < yuvSize / 2; ++i)
	{
		uchar uData = *src++;
		uchar yData = *src++;
		uchar vData = *src++;

		int temp(0);

		temp = _YUV_GET_B(yData, uData, vData);
		temp = (temp > 255 ? 255 : temp);
		temp = (temp < 0 ? 0 : temp);
		*dst++ = temp;

		temp = _YUV_GET_G(yData, uData, vData);
		temp = (temp > 255 ? 255 : temp);
		temp = (temp < 0 ? 0 : temp);
		*dst++ = temp;

		temp = _YUV_GET_R(yData, uData, vData);
		temp = (temp > 255 ? 255 : temp);
		temp = (temp < 0 ? 0 : temp);
		*dst++ = temp;

		yData = *src++;

		temp = _YUV_GET_B(yData, uData, vData);
		temp = (temp > 255 ? 255 : temp);
		temp = (temp < 0 ? 0 : temp);
		*dst++ = temp;

		temp = _YUV_GET_G(yData, uData, vData);
		temp = (temp > 255 ? 255 : temp);
		temp = (temp < 0 ? 0 : temp);
		*dst++ = temp;

		temp = _YUV_GET_R(yData, uData, vData);
		temp = (temp > 255 ? 255 : temp);
		temp = (temp < 0 ? 0 : temp);
		*dst++ = temp;
	}
}

void ImageProcess::yuv444ToBgr(const uchar* yuvData, int yuvWidth, int yuvHeight, uchar* bgrData)
{
	if (!yuvData || yuvWidth <= 0 || yuvHeight <= 0 || !bgrData)
	{
		return;
	}

	const int yuvSize = yuvWidth * yuvHeight;
	const uchar* src = yuvData;
	uchar* dst = bgrData;

	for (int i = 0; i < yuvSize; ++i)
	{
		uchar yData = *src++;
		uchar uData = *src++;
		uchar vData = *src++;

		int temp(0);

		temp = _YUV_GET_B(yData, uData, vData);
		temp = (temp > 255 ? 255 : temp);
		temp = (temp < 0 ? 0 : temp);
		*dst++ = temp;

		temp = _YUV_GET_G(yData, uData, vData);
		temp = (temp > 255 ? 255 : temp);
		temp = (temp < 0 ? 0 : temp);
		*dst++ = temp;

		temp = _YUV_GET_R(yData, uData, vData);
		temp = (temp > 255 ? 255 : temp);
		temp = (temp < 0 ? 0 : temp);
		*dst++ = temp;
	}
}

void ImageProcess::bgrToYuv422(const uchar* bgrData, int bgrWidth, int bgrHeight, uchar* yuvData)
{
	if (!bgrData || bgrWidth <= 0 || bgrHeight <= 0 || !yuvData)
	{
		return;
	}

	const int bgrSize = bgrWidth * bgrHeight;
	const uchar* src = bgrData;
	uchar* dst = yuvData;

	for (int i = 0; i < bgrSize / 2; i++)
	{
		uchar b0Data = *src++;
		uchar g0Data = *src++;
		uchar r0Data = *src++;

		uchar b1Data = *src++;
		uchar g1Data = *src++;
		uchar r1Data = *src++;

		int temp(0);

		temp = _BGR_GET_U(b0Data, g0Data, r0Data, b1Data, g1Data, r1Data);
		temp = (temp > 255 ? 255 : temp);
		temp = (temp < 0 ? 0 : temp);
		*dst++ = temp;

		temp = _BGR_GET_Y(b0Data, g0Data, r0Data);
		temp = (temp > 255 ? 255 : temp);
		temp = (temp < 0 ? 0 : temp);
		*dst++ = temp;

		temp = _BGR_GET_V(b0Data, g0Data, r0Data, b1Data, g1Data, r1Data);
		temp = (temp > 255 ? 255 : temp);
		temp = (temp < 0 ? 0 : temp);
		*dst++ = temp;

		temp = _BGR_GET_Y(b1Data, g1Data, r1Data);
		temp = (temp > 255 ? 255 : temp);
		temp = (temp < 0 ? 0 : temp);
		*dst++ = temp;
	}
}

void ImageProcess::rgbToBgr(uchar* data, int width, int height)
{
	if (!data || width <= 0 || height <= 0)
		return;

	int r = 0, g = 0, b = 0;

	for (int i = 0; i < width; ++i)
	{
		for (int j = 0; j < height; ++j)
		{
			r = data[0];
			g = data[1];
			b = data[2];

			data[0] = b;
			data[1] = g;
			data[2] = r;
			data += 3;
		}
	}
	return;
}

void ImageProcess::rgbToBgr(const uchar* src, int width, int height, uchar* dst)
{
	if (!src || width <= 0 || height <= 0 || !dst)
		return;

	int r = 0, g = 0, b = 0;

	for (int i = 0; i < width; ++i)
	{
		for (int j = 0; j < height; ++j)
		{
			r = src[0];
			g = src[1];
			b = src[2];

			dst[0] = b;
			dst[1] = g;
			dst[2] = r;
			src += 3;
			dst += 3;
		}
	}
	return;
}

void ImageProcess::bgrToRgb(uchar* data, int width, int height)
{
	if (!data || width <= 0 || height <= 0)
		return;

	int r = 0, g = 0, b = 0;

	for (int i = 0; i < width; ++i)
	{
		for (int j = 0; j < height; ++j)
		{
			b = data[0];
			g = data[1];
			r = data[2];

			data[0] = r;
			data[1] = g;
			data[2] = b;
			data += 3;
		}
	}
	return;
}

void ImageProcess::bgrToRgb(const uchar* src, int width, int height, uchar* dst)
{
	if (!src || width <= 0 || height <= 0 || !dst)
		return;

	int r = 0, g = 0, b = 0;

	for (int i = 0; i < width; ++i)
	{
		for (int j = 0; j < height; ++j)
		{
			b = src[0];
			g = src[1];
			r = src[2];

			dst[0] = r;
			dst[1] = g;
			dst[2] = b;
			src += 3;
			dst += 3;
		}
	}
	return;
}

QImage ImageProcess::cvMatToQImage(const cv::Mat& mat, const cv::Size& resize, QImage::Format fmt)
{
	if (mat.empty())
	{
		return QImage();
	}

	cv::Mat temp;
	if (mat.channels() == 1)
	{
		cv::cvtColor(mat, temp, cv::COLOR_GRAY2RGB);
	}
	else if (mat.channels() == 3)
	{
		cv::cvtColor(mat, temp, cv::COLOR_BGR2RGB);
	}

	if (!resize.empty() && mat.size() != resize)
	{
		cv::resize(temp, temp, resize);
	}
	return QImage(temp.data, temp.cols, temp.rows, fmt).copy(0, 0, temp.cols, temp.rows);
}

QPixmap ImageProcess::cvMatToQPixmap(const cv::Mat& mat, const cv::Size& resize, QImage::Format fmt)
{
	return QPixmap::fromImage(cvMatToQImage(mat, resize, fmt));
}

void ImageProcess::bayer8RgToBgr(const uchar* src, int width, int height, uchar* dst)
{
	cv::Mat bayer8(cv::Size(width, height), CV_8UC1, (void*)src);
	cv::Mat bgr;
	cv::cvtColor(bayer8, bgr, CV_BayerRG2BGR);
	memcpy(dst, bgr.data, width * height * 3);
}

void ImageProcess::bayer10RgToBgr(const uchar* src, int width, int height, uchar* dst)
{
	cv::Mat bayer10(cv::Size(width, height), CV_16SC1, (void*)src);
	cv::Mat bayer8;
	cv::convertScaleAbs(bayer10, bayer8, 0.25);
	cv::Mat bgr;
	cv::cvtColor(bayer8, bgr, CV_BayerRG2BGR);
	memcpy(dst, bgr.data, width * height * 3);
}

void ImageProcess::bayer12RgToBgr(const uchar* src, int width, int height, uchar* dst)
{
	cv::Mat bayer12(cv::Size(width, height), CV_16UC1, (void*)src);
	cv::Mat bayer8, bgr;
	cv::convertScaleAbs(bayer12, bayer8, 0.0625);
	cv::cvtColor(bayer8, bgr, CV_BayerRG2BGR);
	memcpy(dst, bgr.data, width * height * 3);
}

void ImageProcess::bayer8BgToBgr(const uchar* src, int width, int height, uchar* dst)
{
	cv::Mat bayer8(cv::Size(width, height), CV_8UC1, (void*)src);
	cv::Mat bgr;
	cv::cvtColor(bayer8, bgr, CV_BayerBG2BGR);
	memcpy(dst, bgr.data, width * height * 3);
}

void ImageProcess::bayer10BgToBgr(const uchar* src, int width, int height, uchar* dst)
{
	cv::Mat bayer10(cv::Size(width, height), CV_16SC1, (void*)src);
	cv::Mat bayer8;
	cv::convertScaleAbs(bayer10, bayer8, 0.25);
	cv::Mat bgr;
	cv::cvtColor(bayer8, bgr, CV_BayerBG2BGR);
	memcpy(dst, bgr.data, width * height * 3);
}

void ImageProcess::bayer12BgToBgr(const uchar* src, int width, int height, uchar* dst)
{
	cv::Mat bayer12(cv::Size(width, height), CV_16UC1, (void*)src);
	cv::Mat bayer8, bgr;
	cv::convertScaleAbs(bayer12, bayer8, 0.0625);
	cv::cvtColor(bayer8, bgr, CV_BayerBG2BGR);
	memcpy(dst, bgr.data, width * height * 3);
}

void ImageProcess::bayer8GbToBgr(const uchar* src, int width, int height, uchar* dst)
{
	cv::Mat bayer8(cv::Size(width, height), CV_8UC1, (void*)src);
	cv::Mat bgr;
	cv::cvtColor(bayer8, bgr, CV_BayerGB2BGR);
	memcpy(dst, bgr.data, width * height * 3);
}

void ImageProcess::bayer10GbToBgr(const uchar* src, int width, int height, uchar* dst)
{
	cv::Mat bayer10(cv::Size(width, height), CV_16SC1, (void*)src);
	cv::Mat bayer8;
	cv::convertScaleAbs(bayer10, bayer8, 0.25);
	cv::Mat bgr;
	cv::cvtColor(bayer8, bgr, CV_BayerGB2BGR);
	memcpy(dst, bgr.data, width * height * 3);
}

void ImageProcess::bayer12GbToBgr(const uchar* src, int width, int height, uchar* dst)
{
	cv::Mat bayer12(cv::Size(width, height), CV_16UC1, (void*)src);
	cv::Mat bayer8, bgr;
	cv::convertScaleAbs(bayer12, bayer8, 0.0625);
	cv::cvtColor(bayer8, bgr, CV_BayerGB2BGR);
	memcpy(dst, bgr.data, width * height * 3);
}

void ImageProcess::bayer8GrToBgr(const uchar* src, int width, int height, uchar* dst)
{
	cv::Mat bayer8(cv::Size(width, height), CV_8UC1, (void*)src);
	cv::Mat bgr;
	cv::cvtColor(bayer8, bgr, CV_BayerGR2BGR);
	memcpy(dst, bgr.data, width * height * 3);
}

void ImageProcess::bayer10GrToBgr(const uchar* src, int width, int height, uchar* dst)
{
	cv::Mat bayer10(cv::Size(width, height), CV_16SC1, (void*)src);
	cv::Mat bayer8;
	cv::convertScaleAbs(bayer10, bayer8, 0.25);
	cv::Mat bgr;
	cv::cvtColor(bayer8, bgr, CV_BayerGR2BGR);
	memcpy(dst, bgr.data, width * height * 3);
}

void ImageProcess::bayer12GrToBgr(const uchar* src, int width, int height, uchar* dst)
{
	cv::Mat bayer12(cv::Size(width, height), CV_16UC1, (void*)src);
	cv::Mat bayer8, bgr;
	cv::convertScaleAbs(bayer12, bayer8, 0.0625);
	cv::cvtColor(bayer8, bgr, CV_BayerGR2BGR);
	memcpy(dst, bgr.data, width * height * 3);
}

void ImageProcess::setTextFont(const QString& fontName, int id)
{
	auto&& data = fontName.toLocal8Bit();
	m_ft2Data->loadFontData(data.constData(), id);
}

void ImageProcess::putText(cv::InputOutputArray img, const QString& text, cv::Point org, int fontHeight, cv::Scalar color, int thickness, cv::LineTypes lineType, bool bottomLeftOrigin)
{
	m_ft2Lock.lock();
	m_ft2Data->putText(img, text.toStdString(), org, fontHeight, color, thickness, lineType, bottomLeftOrigin);
	m_ft2Lock.unlock();
}

cv::Size ImageProcess::getTextSize(const QString& text, int fontHeight, int thickness, int* baseLine)
{
	int _baseLine = 0;
	cv::Size size;
	m_ft2Lock.lock();
	auto&& byte = text.toLocal8Bit();
	size = m_ft2Data->getTextSize(byte.data(), fontHeight, thickness,
		baseLine ? baseLine : &_baseLine);
	m_ft2Lock.unlock();
	return size;
}

cv::Point ImageProcess::getCenterPoint(cv::Size imgSize, const QString& text,
	int fontHeight, int thickness)
{
	cv::Size&& size = getTextSize(text, fontHeight, thickness);
	return cv::Point((imgSize.width - size.width) / 2, (imgSize.height + size.height) / 2);
}

void ImageProcess::putTextOnCenter(cv::Mat& img, const QString& text,
	int fontHeight, cv::Scalar color, cv::Point repair, int thickness)
{
	cv::Point&& point = getCenterPoint(img.size(), text, fontHeight, thickness);
	putText(img, text, point + repair, fontHeight, color, thickness);
}

int ImageProcess::getFps()
{
	static int fps = 0;
	static double last = cv::getTickCount() / cv::getTickFrequency() * 1000;
	static int frame = 0;
	++frame;
	double curr = cv::getTickCount() / cv::getTickFrequency() * 1000;
	if (curr - last > 1000.0f)
	{
		fps = frame;
		frame = 0;
		last = curr;
	}
	return fps;
}

void ImageProcess::putFps(cv::Mat& img, double fontScale, int thickness,
	const cv::Scalar& color, cv::Point point)
{
	int fps = getFps();
	char data[32] = { 0 };
	sprintf_s(data, "FPS:%02d/s", fps);
	int baseLine = 0;
	cv::Size&& size = cv::getTextSize(data, 1, fontScale, thickness, &baseLine);
	cv::Point p;
	if (point.x != -1 && point.y != -1)
	{
		p = point;
	}
	else
	{
		p.x = img.cols - size.width;
		p.y = size.height + baseLine;
	}
	cv::putText(img, data, p, 1, fontScale, color, thickness);
}

cv::Ptr<cv::freetype::FreeType2> ImageProcess::createFreeType2()
{
	char directory[256] = { 0 }, font[256] = { 0 };
	if (GetWindowsDirectoryA(directory, sizeof(directory)))
		sprintf_s(font, "%s\\Fonts\\simhei.ttf", directory);
	else
		sprintf_s(font, "C:\\Windows\\Fonts\\simhei.ttf");
	auto freeType = cv::freetype::createFreeType2();
	freeType->loadFontData(font, 0);
	return freeType;
}

OpenCV下载链接:

opencv3.4.14(带freetype)-C++文档类资源-CSDN文库

使用方法:

#include "MilCap.h"

int main(int argc,char** argv)
{
    QApplication a(argc,argv);
    //以下仅供参考,实际需要在继承QWidget或QDialog或QMainWindow中使用.

    CapBase* base = new(std::nothrow) MilCap;
    if (!base)
        return -1;
    
    //连接你的集成至QObject的类,这里的&Base::updateImageSlot需要替换为你的槽函数.
    /*参考
    void Dt::MainDlg::updateImageSlot(const QPixmap& pixmap)
    {
        //这里是你的QLabel控件
	    ui.imageLabel->setPixmap(pixmap);
    }
    */ 
    connect(base , QPIX_SIGNAL, this, &Dt::MainDlg::updateImageSlot);

    //设置图像处理,比如我想在采集到图片上输出一个文本
    base->setImageProc([&](cv::Mat& mat) {
        static int fontFace = CV_FONT_HERSHEY_SIMPLEX;
		static double fontScale = 0.5;
		static int thickness = 1;
		static int baseLine = 0;

		std::string text("I love C and C++");
		auto&& size = cv::getTextSize(text, fontFace, fontScale, thickness, &baseLine);
		cv::putText(mat, text, cv::Point(rect.x, rect.y + size.height), fontFace, fontScale, CV_RGB(255, 255, 0), thickness);
    });
    
    //设置图像的大小
    base->setImageScaleSize(640, 480);

    //打开采集卡设备
    base->open(0);
    
    //调用startCapture开始采集图像
    base->startCapture();

    //调用stopCapture停止采集图像
    base->stopCapture();
    
    //关闭采集卡设备
    base->close();
    
    return a.exec();
}

  • 5
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值