//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(¤tImage);
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();
}