校正流程
This commit is contained in:
parent
14c3b8494a
commit
79b5b1f8a4
|
@ -2,8 +2,35 @@
|
|||
|
||||
int CISTestImageProcess::test(const cv::Mat& image, CISTestResult& result)
|
||||
{
|
||||
std::vector<cv::RotatedRect> marks;
|
||||
findMarks(image, marks);
|
||||
//std::vector<cv::RotatedRect> marks;
|
||||
//int res = findMarks(image, marks);
|
||||
//return res;
|
||||
|
||||
if (image.channels() != 3)
|
||||
return -1;
|
||||
|
||||
cv::Mat hsv;
|
||||
cv::cvtColor(image, hsv, cv::COLOR_BGR2HSV_FULL);
|
||||
std::vector<cv::Mat> hsv_channels;
|
||||
cv::split(hsv, hsv_channels);
|
||||
|
||||
cv::Mat mask_s, range_h, range_temp;
|
||||
cv::inRange(hsv_channels[1], 100, 255, mask_s); //饱和度在[50, 220]的像素
|
||||
|
||||
//cv::imwrite("range1.jpg", mask_s);
|
||||
cv::inRange(hsv_channels[0], 0, 84, range_h); //饱和度在[220, 255]的像素
|
||||
cv::inRange(hsv_channels[0], 213, 255, range_temp); //饱和度在[220, 255]的像素
|
||||
//cv::imwrite("range3.jpg", range_temp);
|
||||
range_h &= mask_s;
|
||||
range_h |= range_temp & mask_s;
|
||||
findEllipse(range_h, result.scaleXY1);
|
||||
cv::inRange(hsv_channels[0], 42, 170, range_h); //饱和度在[220, 255]的像素
|
||||
range_h &= mask_s;
|
||||
findEllipse(range_h, result.scaleXY2);
|
||||
cv::inRange(hsv_channels[0], 128, 213, range_h); //饱和度在[220, 255]的像素
|
||||
range_h &= mask_s;
|
||||
findEllipse(range_h, result.scaleXY3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -69,6 +96,39 @@ void CISTestImageProcess::findContours(const cv::Mat& src, std::vector<std::vect
|
|||
storage.release();
|
||||
}
|
||||
|
||||
void CISTestImageProcess::convexHull(const std::vector<cv::Point>& src, std::vector<cv::Point>& dst, bool clockwise)
|
||||
{
|
||||
CvMemStorage* storage = cvCreateMemStorage(); //
|
||||
CvSeq* ptseq = cvCreateSeq(CV_SEQ_KIND_GENERIC | CV_32SC2, sizeof(CvContour), sizeof(CvPoint), storage); //ptseqstorage
|
||||
|
||||
//将src的点集填充至ptseq
|
||||
for (const cv::Point& item : src)
|
||||
{
|
||||
CvPoint p;
|
||||
p.x = item.x;
|
||||
p.y = item.y;
|
||||
cvSeqPush(ptseq, &p);
|
||||
}
|
||||
|
||||
//获取轮廓点
|
||||
CvSeq* hull = cvConvexHull2(ptseq, nullptr, clockwise ? CV_CLOCKWISE : CV_COUNTER_CLOCKWISE, 0);
|
||||
|
||||
if (hull == nullptr)
|
||||
{
|
||||
//释放storage
|
||||
cvReleaseMemStorage(&storage);
|
||||
return;
|
||||
}
|
||||
|
||||
//填充dst
|
||||
dst.clear();
|
||||
for (int i = 0, hullCount = hull->total; i < hullCount; i++)
|
||||
dst.push_back(**CV_GET_SEQ_ELEM(CvPoint*, hull, i));
|
||||
|
||||
//释放storage
|
||||
cvReleaseMemStorage(&storage);
|
||||
}
|
||||
|
||||
int CISTestImageProcess::findPaperContour(const std::vector<std::vector<cv::Point>>& contours, const std::vector<cv::Vec4i>& hierarchy, cv::RotatedRect& paperRect)
|
||||
{
|
||||
std::vector<cv::Point> maxContour;
|
||||
|
@ -116,27 +176,38 @@ int CISTestImageProcess::classfiyContours(const std::vector<std::vector<cv::Poin
|
|||
return 0;
|
||||
}
|
||||
|
||||
int CISTestImageProcess::findMarks(const cv::Mat& image, std::vector<cv::RotatedRect>& marks)
|
||||
int CISTestImageProcess::findEllipse(const cv::Mat& image, double& scale_xy, double areaThre)
|
||||
{
|
||||
int res = 0;
|
||||
cv::Mat thre;
|
||||
if (image.channels() != 1)
|
||||
{
|
||||
cv::cvtColor(image, thre, cv::COLOR_BGR2GRAY);
|
||||
cv::threshold(thre, thre, 127, 255, cv::THRESH_BINARY);
|
||||
}
|
||||
else
|
||||
cv::threshold(image, thre, 127, 255, cv::THRESH_BINARY);
|
||||
|
||||
//cv::imwrite("range2.jpg", image);
|
||||
std::vector<std::vector<cv::Point>> contours;
|
||||
std::vector<cv::Vec4i> hierarchy;
|
||||
findContours(thre, contours, hierarchy, cv::RETR_CCOMP, cv::CHAIN_APPROX_SIMPLE);
|
||||
|
||||
cv::RotatedRect paperRect;
|
||||
res = findPaperContour(contours, hierarchy, paperRect);
|
||||
findContours(image, contours, hierarchy, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
|
||||
|
||||
if (res != 0)
|
||||
return res;
|
||||
std::vector<cv::Point> maxContour;
|
||||
for (std::vector<std::vector<cv::Point>>::iterator iter = contours.begin(); iter != contours.end(); iter++)
|
||||
if (cv::contourArea(*iter) > areaThre)
|
||||
for (const auto& item : *iter)
|
||||
maxContour.push_back(item);
|
||||
|
||||
return res;
|
||||
convexHull(maxContour, maxContour);
|
||||
|
||||
cv::RotatedRect box = cv::fitEllipse(maxContour);
|
||||
|
||||
if (box.angle < -45)
|
||||
{
|
||||
box.angle += 90;
|
||||
float temp = box.size.width;
|
||||
box.size.width = box.size.height;
|
||||
box.size.height = temp;
|
||||
}
|
||||
if (box.angle > 45)
|
||||
{
|
||||
box.angle -= 90;
|
||||
float temp = box.size.width;
|
||||
box.size.width = box.size.height;
|
||||
box.size.height = temp;
|
||||
}
|
||||
areaThre = box.size.width / box.size.height;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -50,6 +50,8 @@ private:
|
|||
static void findContours(const cv::Mat& src, std::vector<std::vector<cv::Point>>& contours, std::vector<cv::Vec4i>& hierarchy,
|
||||
int retr = cv::RETR_LIST, int method = cv::CHAIN_APPROX_SIMPLE, cv::Point offset = cv::Point(0, 0));
|
||||
|
||||
static void convexHull(const std::vector<cv::Point>& src, std::vector<cv::Point>& dst, bool clockwise = false);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
|
@ -63,12 +65,8 @@ private:
|
|||
std::vector<std::vector<cv::Point>>& colorBlocks,
|
||||
std::vector<std::vector<cv::Point>>& grayBlocks);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="vector"></param>
|
||||
/// <param name=""></param>
|
||||
static int findMarks(const cv::Mat& image, std::vector<cv::RotatedRect>& marks);
|
||||
|
||||
static int findEllipse(const cv::Mat& image, double& scale_xy, double areaThre = 100 * 100);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -172,6 +172,7 @@ void hg_scanner_200::thread_handle_usb_read(void)
|
|||
ret = io_->read_bulk(&msg[0], &count);
|
||||
if (ret == SCANNER_ERR_OK)
|
||||
{
|
||||
status_ = ret = SCANNER_ERR_DEVICE_AUTO_FAIL_INFO;
|
||||
char buf[1024];
|
||||
strcpy(buf, msg.c_str());
|
||||
notify_ui_working_status(buf, SANE_EVENT_STATUS, status_);
|
||||
|
|
|
@ -152,9 +152,10 @@ void hg_scanner_300::thread_handle_usb_read(void)
|
|||
ret = io_->read_bulk(&msg[0], &count);
|
||||
if (ret == SCANNER_ERR_OK)
|
||||
{
|
||||
status_= ret = SCANNER_ERR_DEVICE_AUTO_FAIL_INFO;
|
||||
char buf[1024];
|
||||
strcpy(buf, msg.c_str());
|
||||
notify_ui_working_status(buf, SANE_EVENT_STATUS, status_);
|
||||
notify_ui_working_status(buf, SANE_EVENT_STATUS, status_);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -339,12 +340,12 @@ int hg_scanner_300::get_scanner_status(USBCB &usb)
|
|||
int ret = SCANNER_ERR_OK;
|
||||
|
||||
usb = { setting3288dsp::GET_DSP_STATUS, 0, 0};
|
||||
|
||||
io_->set_timeout(500); //必要延时,且不能小于这个数值
|
||||
ret = writeusb(usb);
|
||||
if (ret != SCANNER_ERR_OK)
|
||||
return ret;
|
||||
|
||||
//io_->set_timeout(200); //必要延时,且不能小于这个数值
|
||||
io_->set_timeout(500); //必要延时,且不能小于这个数值
|
||||
|
||||
ret = readusb(usb);
|
||||
|
||||
|
|
|
@ -154,6 +154,7 @@ void hg_scanner_400::thread_handle_usb_read(void)
|
|||
ret = io_->read_bulk(&msg[0], &count);
|
||||
if (ret == SCANNER_ERR_OK)
|
||||
{
|
||||
status_ = ret = SCANNER_ERR_DEVICE_AUTO_FAIL_INFO;
|
||||
char buf[1024];
|
||||
strcpy(buf, msg.c_str());
|
||||
notify_ui_working_status(buf, SANE_EVENT_STATUS, status_);
|
||||
|
|
Loading…
Reference in New Issue