diff --git a/hgdriver/ImageProcess/ImageApplyHeaders.h b/hgdriver/ImageProcess/ImageApplyHeaders.h index bd11b6f..780d075 100644 --- a/hgdriver/ImageProcess/ImageApplyHeaders.h +++ b/hgdriver/ImageProcess/ImageApplyHeaders.h @@ -32,4 +32,5 @@ #include "ImageApplySplit.h" #include "CISTestImageProcess.h" #include "ImageApplyColorCastCorrect.h" +#include "LineContinuityDetection.h" #endif diff --git a/hgdriver/ImageProcess/LineContinuityDetection.cpp b/hgdriver/ImageProcess/LineContinuityDetection.cpp new file mode 100644 index 0000000..190f4c0 --- /dev/null +++ b/hgdriver/ImageProcess/LineContinuityDetection.cpp @@ -0,0 +1,141 @@ +#include "LineContinuityDetection.h" + +LineContinuityDetection::LineContinuityDetection() +{ +} + +bool LineContinuityDetection::isContinuous(const cv::Mat& image, double area_threshold) +{ + cv::Mat thre; + if (image.channels() != 1) + { + cv::cvtColor(image, thre, cv::COLOR_BGR2GRAY); + cv::threshold(thre, thre, 127, 255, cv::THRESH_OTSU); + } + else + cv::threshold(image, thre, 127, 255, cv::THRESH_OTSU); + + std::vector> contours; + std::vector hierarchy; + myFindContours(thre, contours, hierarchy, cv::RETR_TREE); + + return findBlock(contours, hierarchy, area_threshold); +} + +void LineContinuityDetection::myFindContours(const cv::Mat& src, std::vector>& contours, std::vector& hierarchy, int retr, int method, cv::Point offset) +{ +#if CV_VERSION_REVISION <= 6 + CvMat c_image = src; +#else + CvMat c_image; + c_image = cvMat(src.rows, src.cols, src.type(), src.data); + c_image.step = src.step[0]; + c_image.type = (c_image.type & ~cv::Mat::CONTINUOUS_FLAG) | (src.flags & cv::Mat::CONTINUOUS_FLAG); +#endif + cv::MemStorage storage(cvCreateMemStorage()); + CvSeq* _ccontours = nullptr; + +#if CV_VERSION_REVISION <= 6 + cvFindContours(&c_image, storage, &_ccontours, sizeof(CvContour), retr, method, CvPoint(offset)); +#else + cvFindContours(&c_image, storage, &_ccontours, sizeof(CvContour), retr, method, CvPoint{ offset.x, offset.y }); +#endif + if (!_ccontours) + { + contours.clear(); + return; + } + cv::Seq all_contours(cvTreeToNodeSeq(_ccontours, sizeof(CvSeq), storage)); + size_t total = all_contours.size(); + contours.resize(total); + + cv::SeqIterator it = all_contours.begin(); + for (size_t i = 0; i < total; i++, ++it) + { + CvSeq* c = *it; + reinterpret_cast(c)->color = static_cast(i); + int count = c->total; + int* data = new int[static_cast(count * 2)]; + cvCvtSeqToArray(c, data); + for (int j = 0; j < count; j++) + { + contours[i].push_back(cv::Point(data[j * 2], data[j * 2 + 1])); + } + delete[] data; + } + + hierarchy.resize(total); + it = all_contours.begin(); + for (size_t i = 0; i < total; i++, ++it) + { + CvSeq* c = *it; + int h_next = c->h_next ? reinterpret_cast(c->h_next)->color : -1; + int h_prev = c->h_prev ? reinterpret_cast(c->h_prev)->color : -1; + int v_next = c->v_next ? reinterpret_cast(c->v_next)->color : -1; + int v_prev = c->v_prev ? reinterpret_cast(c->v_prev)->color : -1; + hierarchy[i] = cv::Vec4i(h_next, h_prev, v_next, v_prev); + } + + storage.release(); +} + +bool LineContinuityDetection::findBlock(const std::vector>& contours, const std::vector& hierarchy, double area_threshold) +{ + if (contours.empty()) + return false; + + std::vector rects; + + for (size_t i = 0; i < contours.size(); i++) + { + cv::RotatedRect rect = minAreaRect(contours[i]); + rects.push_back(rect); + } + + std::vector max_index; + std::vector max_area; + for (size_t i = 0; i < 5; i++) + { + max_index.push_back(0); + max_area.push_back(0); + } + for (size_t i = 0; i < rects.size(); i++) + { + float area = rects[i].size.area(); + for (size_t j = 0; j < 5; j++) + { + if (area > max_area[j]) + { + max_index.insert(max_index.begin() + j, i); + max_area.insert(max_area.begin() + j, area); + + max_index.erase(max_index.begin() + 5); + max_area.erase(max_area.begin() + 5); + + break; + } + } + } + + for (size_t i = 1; i < 5; i++) + { + int child_count = 0; + int index_temp = hierarchy[max_index[i]][2]; + if (index_temp < 0) + return false; + + child_count++; + while (hierarchy[index_temp][0] != -1) + { + if (rects[index_temp].size.area() > area_threshold) + child_count++; + + index_temp = hierarchy[index_temp][0]; + } + + if (child_count != 4) + return false; + } + + return true; +} diff --git a/hgdriver/ImageProcess/LineContinuityDetection.h b/hgdriver/ImageProcess/LineContinuityDetection.h new file mode 100644 index 0000000..654772f --- /dev/null +++ b/hgdriver/ImageProcess/LineContinuityDetection.h @@ -0,0 +1,29 @@ +#ifndef LINE_CONTINUITY_DETECTION_H +#define LINE_CONTINUITY_DETECTION_H + +#include + +class LineContinuityDetection +{ +public: + LineContinuityDetection(); + + static bool isContinuous(const cv::Mat& image, double area_threshold = 100); + +private: + /// +/// 获取连通区域轮廓 +/// +/// 源图像 +/// 结果轮廓集 +/// 轮廓集的排序关系。与contours的数量对应,受retr选项不同,排序会有变化 +/// 轮廓集排序方式,默认为链式排序 +/// 查找算法选择,默认为普通查找 +/// 查找起始点,默认为(0,0)点 + static void myFindContours(const cv::Mat& src, std::vector>& contours, std::vector& hierarchy, + int retr = cv::RETR_LIST, int method = cv::CHAIN_APPROX_SIMPLE, cv::Point offset = cv::Point(0, 0)); + + static bool findBlock(const std::vector>& contours, const std::vector& hierarchy, double area_threshold); +}; + +#endif //LINE_CONTINUITY_DETECTION_H \ No newline at end of file diff --git a/hgdriver/hgdev/image_process.cpp b/hgdriver/hgdev/image_process.cpp index 23231f3..fec68ae 100644 --- a/hgdriver/hgdev/image_process.cpp +++ b/hgdriver/hgdev/image_process.cpp @@ -1410,7 +1410,14 @@ namespace hg_imgproc return ret; //cv::imwrite("CISTestImageProcess.jpg",mats[i]); } - + int lost_frame_test() + { + if (mats_.empty()) + { + return SCANNER_ERR_NO_DATA; + } + return LineContinuityDetection::isContinuous(mats_[0], 100); //妫娴嬩竴闈㈠氨琛 + } int correction_image(cv::Mat &flat_lut, cv::Mat black_mat, cv::Mat white_mat) { flat_lut = creatLUTData(black_mat, white_mat);//璁$畻LUT 鏌ュ艰〃 @@ -2024,6 +2031,11 @@ namespace hg_imgproc { return ((imgproc*)himg)->color_cast_correction(); } + int lost_frame_test(HIMGPRC himg) + { + return ((imgproc*)himg)->lost_frame_test(); + return 0; + } int final(HIMGPRC himg) { return ((imgproc*)himg)->final(); diff --git a/hgdriver/hgdev/image_process.h b/hgdriver/hgdev/image_process.h index a316ee1..c4bcb41 100644 --- a/hgdriver/hgdev/image_process.h +++ b/hgdriver/hgdev/image_process.h @@ -207,6 +207,7 @@ namespace hg_imgproc int size_detection(HIMGPRC himg); int cis_test_image(HIMGPRC himg, CISTestImageProcess::CISTestResult& res); int color_cast_correction(HIMGPRC himg); + int lost_frame_test(HIMGPRC himg); int final(HIMGPRC himg);