123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319 |
- #include "Export.h"
- // 将图像转成所需的灰度图,且进行缩放
- bool ConvertImage(const char* srcImgData, int imgwidth, int imgheight, ColorType colorType,
- int newW, int newH, const char* dstImgData)
- {
- try
- {
- // 检查通道数
- if (colorType != Gray8 && colorType != Rgb && colorType != Bgr && colorType != Bgra && colorType != Rgba)
- {
- //ErrorMsg::SetErrorMsg(ConvertError, { "unexpected colorType." });
- return false;
- }
- // 检查图像尺寸
- if (imgwidth <= 0 || imgheight <= 0)
- {
- //ErrorMsg::SetErrorMsg(ConvertError, { "unexpected image size." });
- return false;
- }
- // 检查指针
- if (srcImgData == nullptr)
- {
- //ErrorMsg::SetErrorMsg(ConvertError, { "unexpected image data pointer." });
- return false;
- }
- cv::Size imgSize = cv::Size(imgwidth, imgheight);
- cv::Mat img;
- cv::Mat imgGray = cv::Mat(imgSize, CV_8UC1);
- switch (colorType)
- {
- case Gray8:
- img = cv::Mat(imgSize, CV_8UC(1), (void*)srcImgData);
- imgGray = img.clone();
- break;
- case Rgb:
- img = cv::Mat(imgSize, CV_8UC(3), (void*)srcImgData);
- cvtColor(img, imgGray, cv::COLOR_RGB2GRAY);
- break;
- case Bgr:
- img = cv::Mat(imgSize, CV_8UC(3), (void*)srcImgData);
- cvtColor(img, imgGray, cv::COLOR_BGR2GRAY);
- break;
- case Rgba:
- img = cv::Mat(imgSize, CV_8UC(4), (void*)srcImgData);
- cvtColor(img, imgGray, cv::COLOR_RGBA2GRAY);
- break;
- case Bgra:
- img = cv::Mat(imgSize, CV_8UC(4), (void*)srcImgData);
- cvtColor(img, imgGray, cv::COLOR_BGRA2GRAY);
- break;
- }
- img.release();
- cv::Size newSize = cv::Size(newW, newH);//cvSize(120, 120);
- cv::Mat imgResized;
- cv::resize(imgGray, imgResized, newSize);
- imgGray.release();
- ;
- // 去除椒盐噪声
- cv::medianBlur(imgResized, imgResized, 5);
- memcpy((void*)dstImgData, imgResized.data, sizeof(char) * newW * newH);
- imgResized.release();
- return true;
- }
- catch (const std::exception& ex)
- {
- //ErrorMsg::SetErrorMsg(ConvertError, { ex.what() });
- return false;
- }
- }
- // 对图像进行canny运算,计算得到的边缘所占的比值
- bool ProcessOneImage(const char* imgData, int imgwidth, int imgheight, ColorType colorType, double& cannyRatio)
- {
- try
- {
- // 检查通道数
- if (colorType != Gray8 && colorType != Rgb && colorType != Bgr && colorType != Bgra && colorType != Rgba)
- {
- //ErrorMsg::SetErrorMsg(CannyError, { "unexpected colorType." });
- return false;
- }
- // 检查图像尺寸
- if (imgwidth <= 0 || imgheight <= 0)
- {
- //ErrorMsg::SetErrorMsg(CannyError, { "unexpected image size." });
- return false;
- }
- // 检查指针
- if (imgData == nullptr)
- {
- //ErrorMsg::SetErrorMsg(CannyError, { "unexpected image data pointer." });
- return false;
- }
- int channel = 1;
- switch (colorType)
- {
- case Gray8:
- channel = 1;
- break;
- case Rgb:
- case Bgr:
- channel = 3;
- break;
- case Rgba:
- case Bgra:
- channel = 4;
- break;
- }
- // 复制图像
- cv::Size imgSize = cv::Size(imgwidth, imgheight);
- cv::Mat img = cv::Mat(imgSize, CV_8UC(channel));
- memcpy(img.data, imgData, imgwidth * imgheight * channel);
- // 计算canny系数
- cannyProcess(img, cannyRatio);
- return true;
- }
- catch (const std::exception& ex)
- {
- //ErrorMsg::SetErrorMsg(CannyError, { ex.what() });
- return false;
- }
- }
- // 根据累积的一些信息,判断当前图像的状态
- CurrentVideoState JudgeImage(double* diffData, double* corrData, double* cannyData,
- int num, int movingDelayNum, int stationaryDelayNum, int movingDelayTriggerNum, int stationaryDelayTriggerNum, bool manuallyUnfreeze, ExtendState& state)
- {
- try
- {
- double diffVar = 0;
- double cannyVar = 0;
- CurrentVideoState tmp = Notjudged;
- std::vector<double> vDiffData;
- std::vector<double> vCannyData;
- for (int i = 0; i < num; i++)
- {
- vDiffData.push_back(diffData[i]);
- vCannyData.push_back(cannyData[i]);
- }
- if (vDiffData.size() > 1)
- {
- varVector(vDiffData, diffVar);
- cannyVector(vCannyData, cannyVar);
- if ((diffVar > 100 && cannyVar > 0.8) || cannyVar > 2.5)
- {
- tmp = Moving;
- }
- else if (diffVar < 20 || cannyVar < 0.5)
- {
- tmp = Stationary;
- }
- else
- {
- tmp = Notjudged;
- }
- }
- else
- {
- tmp = Stationary;
- }
- if (tmp != Notjudged)
- {
- if (tmp == Stationary)
- {
- // 如果之前是强制延长Stationary状态,现在已经是真实的判为是静置了,可以把状态量恢复了
- if (state.StationaryExtendedState)
- {
- state.StationaryExtendedNum = 0;
- state.StationaryExtendedState = false;
- }
- if (state.TrueMovingNum > movingDelayTriggerNum || manuallyUnfreeze)
- {
- state.MovingExtendedState = true;
- }
- if (state.MovingExtendedState)
- {
- if (state.MovingExtendedNum < movingDelayNum)
- {
- state.MovingExtendedNum++;
- return Moving;
- }
- // 延迟帧数已经超标,清空状态
- state.TrueMovingNum = 0;
- state.MovingExtendedNum = 0;
- state.MovingExtendedState = false;
- }
- // 如果之前不是静置,则TrueStationary的计数清零
- if (state.LastState)
- {
- state.TrueStationaryNum = 0;
- }
- state.TrueStationaryNum++;
- state.LastState = false;
- return Stationary;
- }
- else if (tmp == Moving)
- {
- // 如果之前是强制延长Moving状态,现在已经是真实的判为是扫查中了,可以把状态量恢复了
- if (state.MovingExtendedState)
- {
- state.MovingExtendedNum = 0;
- state.MovingExtendedState = false;
- }
- if (state.TrueStationaryNum > stationaryDelayTriggerNum)
- {
- state.StationaryExtendedState = true;
- }
- if (state.StationaryExtendedState)
- {
- if (state.StationaryExtendedNum < stationaryDelayNum)
- {
- state.StationaryExtendedNum++;
- return Stationary;
- }
- // 超过限定个数,清空
- state.TrueStationaryNum = 0;
- state.StationaryExtendedNum = 0;
- state.StationaryExtendedState = false;
- }
- // 如果之前不是运行,则TrueMoving的计数清零
- if (!state.LastState)
- {
- state.TrueMovingNum = 0;
- }
- state.TrueMovingNum++;
- state.LastState = true;
- return Moving;
- }
- }
- else
- {
- if (state.LastState)
- {
- return Moving;
- }
- else
- {
- return Stationary;
- }
- }
- }
- catch (const std::exception& ex)
- {
- //ErrorMsg::SetErrorMsg(JudgeError, { ex.what() });
- return HaveError;
- }
- }
- // 对两幅图像进行互相关计算
- double CompareTwoImage(const char* pSrc1, const char* pSrc2, int width, int height, int widthstep, double& corr, double& diff)
- {
- try
- {
- double ratio = 0;
- // 求两幅图的互相关系数
- calcorrcoef((uint8_t*)(pSrc1), (uint8_t*)(pSrc2), width, height, widthstep, corr);
- // corr大于该值,则认为两幅图可能一致,不计算diff(默认为0)
- // corr小于该值,可计算两幅图的差异
- if (corr < 0.999)
- {
- ratio = calDiff((uint8_t*)(pSrc1), (uint8_t*)(pSrc2), width, height, diff);
- }
- return ratio;
- }
- catch (const std::exception& ex)
- {
- //ErrorMsg::SetErrorMsg(ImageDiffError, { ex.what() });
- return 2;
- }
- }
- // 图像数据解码
- bool ImgDataDecode(const uint8_t* srcImgData, const int srcDataSize, ImreadModes imReadMode, ImageInfo* imageInfo)
- {
- std::vector<uchar> dataDecode;
- dataDecode.resize(srcDataSize);
- for (int ni = 0; ni < srcDataSize; ni++)
- {
- dataDecode[ni] = srcImgData[ni];
- }
- cv::Mat imgDecode = cv::imdecode(dataDecode, imReadMode);
- imageInfo->width = imgDecode.cols;
- imageInfo->height = imgDecode.rows;
- auto type = imgDecode.type();
- switch (type)
- {
- case CV_8UC1:
- imageInfo->colorType = Gray8;
- break;
- case CV_8UC3:
- imageInfo->colorType = Bgr;
- break;
- case CV_8UC4:
- imageInfo->colorType = Bgra;
- break;
- default:
- return false;
- }
- return true;
- }
- // 获得解码后的图像尺寸
- int GetDecodedImgSize(const uint8_t* srcImgData, const int srcDataSize, ImreadModes imReadMode)
- {
- std::vector<uchar> dataDecode;
- dataDecode.resize(srcDataSize);
- for (int ni = 0; ni < srcDataSize; ni++)
- {
- dataDecode[ni] = srcImgData[ni];
- }
- cv::Mat imgDecode = cv::imdecode(dataDecode, imReadMode);
- auto total = imgDecode.total();
- auto elemSize = imgDecode.elemSize();
- return total * elemSize;
- }
|