1595 lines
56 KiB
C++
1595 lines
56 KiB
C++
#include <algorithm>
|
||
#include "../external/imgui/imgui.h"
|
||
#include "RecoatCheck.h"
|
||
#include "../LanguageManager.h"
|
||
#include "../Logger.h"
|
||
#include "../job/VolumeCalc.h"
|
||
#include "../config/ConfigManager.h"
|
||
#include "../additional/Calibration.h"
|
||
|
||
#define CLIPPER_SCALE 1.0e9
|
||
|
||
RecoatCheck::RecoatCheck()
|
||
:m_DispTex(0)
|
||
, m_CaptureTex(0)
|
||
{
|
||
InitializeCriticalSection(&cs);
|
||
InitializeCriticalSection(&disp_cs);
|
||
m_DstWidth = 800;
|
||
m_DstHeight = 800;
|
||
m_WarpDst = cv::Mat(cv::Size(m_DstWidth, m_DstHeight), CV_8U);
|
||
m_ExtCfg = ConfigManager::GetInstance()->GetExtCfg();
|
||
m_CameraCalibrationCfg = ConfigManager::GetInstance()->GetCameraCalibrationCfg();
|
||
}
|
||
|
||
RecoatCheck::~RecoatCheck()
|
||
{
|
||
DeleteCriticalSection(&cs);
|
||
DeleteCriticalSection(&disp_cs);
|
||
}
|
||
|
||
float allMasks[5][5] = { { 1, 4, 6, 4, 1 }, //level -- 0
|
||
{ -1, -2, 0, 2, 1 }, //edge -- 1
|
||
{ -1, 0, 2, 0, -1 }, //spot -- 2
|
||
{ -1, 2, 0, -2, 1 }, //wave -- 3
|
||
{ 1, -4, 6, -4, 1 } }; //ripple -- 4
|
||
|
||
cv::Mat RecoatCheck::generateMask2D(float allMasks[5][5], int row1, int row2)
|
||
{
|
||
cv::Mat mask = cv::Mat::zeros(5, 5, CV_32F);
|
||
|
||
for (int i = 0; i < 5; i++) {
|
||
for (int j = 0; j < 5; j++) {
|
||
mask.at<float>(i, j) = (float)(allMasks[row2][j] * allMasks[row1][i]);
|
||
}
|
||
}
|
||
|
||
return mask;
|
||
}
|
||
|
||
bool RecoatCheck::CheckOL(MetaData* metadata, unsigned int layer, unsigned char** img, int width, int high)
|
||
{
|
||
RecoatCheckCfg* rcc = ConfigManager::GetInstance()->GetRecoatCheckCfg();
|
||
if (!rcc->m_Enable)
|
||
return true;
|
||
|
||
if (!img || width <= 0 || high <= 0)
|
||
return true;
|
||
|
||
cv::Mat image(high, width, CV_8U, *img);
|
||
//delete[] * img;
|
||
//*img = nullptr;
|
||
//Mat mask = imread("E:\\prj\\cv\\cv\\x64\\Release\\mask.bmp", ImreadModes::IMREAD_GRAYSCALE);
|
||
//Mat image = imread("E:\\prj\\rc00.bmp", ImreadModes::IMREAD_GRAYSCALE);
|
||
cv::Mat mask = cv::Mat::zeros(image.size(), image.type());
|
||
|
||
// <20><><EFBFBD><EFBFBD> <20>߽<EFBFBD><DFBD><EFBFBD><EFBFBD><EFBFBD>roi<6F><69><EFBFBD><EFBFBD>
|
||
vector<vector<cv::Point>> contour;
|
||
vector<cv::Point> pts;
|
||
pts.push_back(cv::Point(rcc->m_MaskTopLeftX, rcc->m_MaskTopLeftY));
|
||
pts.push_back(cv::Point(rcc->m_MaskTopRightX, rcc->m_MaskTopRightY));
|
||
pts.push_back(cv::Point(rcc->m_MaskBottomRightX, rcc->m_MaskBottomRightY));
|
||
pts.push_back(cv::Point(rcc->m_MaskBottomLeftX, rcc->m_MaskBottomLeftY));
|
||
pts.push_back(cv::Point(rcc->m_MaskTopLeftX, rcc->m_MaskTopLeftY));
|
||
contour.push_back(pts);
|
||
// <20><><EFBFBD><EFBFBD>
|
||
drawContours(mask, contour, 0, cv::Scalar::all(255), -1);
|
||
|
||
//cv::Ptr<cv::CLAHE> clahe = cv::createCLAHE();
|
||
//clahe->setClipLimit(1.5);
|
||
//cv::Mat dst;
|
||
//clahe->apply(image, dst);
|
||
|
||
cv::Mat bg;
|
||
GaussianBlur(image, bg, cv::Size(201, 201), 100);
|
||
cv::Scalar m = mean(bg);
|
||
divide(image, bg, image, m.val[0]);
|
||
|
||
bitwise_and(image, mask, image);
|
||
//imwrite("ffc.bmp", image);
|
||
|
||
cv::Point2f srcTri[4];
|
||
srcTri[0] = cv::Point2f(rcc->m_MaskTopLeftX, rcc->m_MaskTopLeftY);
|
||
srcTri[1] = cv::Point2f(rcc->m_MaskTopRightX, rcc->m_MaskTopRightY);
|
||
srcTri[2] = cv::Point2f(rcc->m_MaskBottomLeftX, rcc->m_MaskBottomLeftY);
|
||
srcTri[3] = cv::Point2f(rcc->m_MaskBottomRightX, rcc->m_MaskBottomRightY);
|
||
cv::Point2f dstTri[4];
|
||
dstTri[0] = cv::Point2f(rcc->m_TransformTopLeftX, rcc->m_TransformTopLeftY);
|
||
dstTri[1] = cv::Point2f(rcc->m_TransformTopRightX, rcc->m_TransformTopRightY);
|
||
dstTri[2] = cv::Point2f(rcc->m_TransformBottomLeftX, rcc->m_TransformBottomLeftY);
|
||
dstTri[3] = cv::Point2f(rcc->m_TransformBottomRightX, rcc->m_TransformBottomRightY);
|
||
cv::Mat warp_mat = getPerspectiveTransform(srcTri, dstTri);
|
||
|
||
dstTri[0] = cv::Point2f(0.f, 0.f);
|
||
dstTri[1] = cv::Point2f(800.f, 0.f);
|
||
dstTri[2] = cv::Point2f(0.f, 800.f);
|
||
dstTri[3] = cv::Point2f(800.f, 800.f);
|
||
cv::Mat disp_warp_mat = getPerspectiveTransform(srcTri, dstTri);
|
||
|
||
cv::Mat laws_mask = generateMask2D(allMasks, 1, 0);
|
||
cv::Mat dst;
|
||
cv::blur(image, dst, cv::Size(3, 3));
|
||
cv::filter2D(dst, dst, -1, laws_mask);
|
||
//dst = dst / 3.0;
|
||
//GaussianBlur(dst, dst, Size(13, 13), 10);
|
||
cv::blur(dst, dst, cv::Size(13, 13));
|
||
|
||
threshold(dst, dst, rcc->m_BinaryThreshold, 255, cv::ThresholdTypes::THRESH_BINARY);
|
||
//Mat element2 = getStructuringElement( MorphShapes::MORPH_ELLIPSE, Size( 2*10 + 1, 2*10+1 ), Point( /*morph_size, morph_size*/ ) );
|
||
//morphologyEx(dst, dst, MORPH_DILATE, element2);
|
||
//morphologyEx(dst, dst, MORPH_ERODE, element2);
|
||
//Mat element3 = getStructuringElement( MorphShapes::MORPH_ELLIPSE, Size( 2*5 + 1, 2*5+1 ), Point( /*morph_size, morph_size*/ ) );
|
||
//morphologyEx(dst, dst, MORPH_OPEN, element3);
|
||
if (isNeedDisp) {
|
||
EnterCriticalSection(&disp_cs);
|
||
cv::warpPerspective(dst, m_WarpDst, disp_warp_mat, m_WarpDst.size());
|
||
vector<vector<cv::Point>> disp_contours;
|
||
vector<cv::Vec4i> disp_hierarchy;
|
||
cv::findContours(m_WarpDst, disp_contours, disp_hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_NONE, cv::Point());
|
||
cv::warpPerspective(image, m_WarpDst, disp_warp_mat, m_WarpDst.size());
|
||
cv::drawContours(m_WarpDst, disp_contours, -1, cv::Scalar(255), 2);
|
||
isDispUpdated = true;
|
||
LeaveCriticalSection(&disp_cs);
|
||
}
|
||
//Mat imageContours;
|
||
//warp_dst.copyTo(imageContours);
|
||
//warpAffine(dst, warp_dst, warp_mat, warp_dst.size());
|
||
//imshow("image", warp_dst);
|
||
|
||
EnterCriticalSection(&cs);
|
||
realc.clear();
|
||
vector<vector<cv::Point>> contours;
|
||
vector<cv::Vec4i> hierarchy;
|
||
cv::findContours(dst, contours, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_NONE, cv::Point());
|
||
for (size_t i = 0; i < contours.size(); i++) {
|
||
vector<cv::Point2f> tmp;
|
||
for (size_t j = 0; j < contours[i].size(); j++) {
|
||
tmp.emplace_back(contours[i][j].x, contours[i][j].y);
|
||
}
|
||
realc.push_back(vector<cv::Point2f>());
|
||
perspectiveTransform(tmp, realc[i], warp_mat);
|
||
}
|
||
m_Solutions.clear();
|
||
LeaveCriticalSection(&cs);
|
||
|
||
if (metadata && layer > 0) {
|
||
GetLayerBorders(metadata, layer, m_Borders);
|
||
bool flag = RecoatCheckByContoursIntersect(m_Borders, realc, metadata);
|
||
EnterCriticalSection(&cs);
|
||
isDrawed = false;
|
||
LeaveCriticalSection(&cs);
|
||
|
||
return flag;
|
||
}
|
||
else {
|
||
return true;
|
||
}
|
||
}
|
||
|
||
void RecoatCheck::DrawPoly(vl::ref<vl::VectorGraphics> vg)
|
||
{
|
||
EnterCriticalSection(&cs);
|
||
if (vg && realc.size() > 0 && !isDrawed) {
|
||
isDrawed = true;
|
||
vg->clear();
|
||
vg->startDrawing();
|
||
vg->setColor(vl::yellow);
|
||
vg->setLineWidth(1.0f);
|
||
vg->currentEffect()->shader()->disable(vl::EEnable::EN_LINE_SMOOTH);
|
||
for (size_t i = 0; i < realc.size(); i++) {
|
||
vector<vl::dvec2> poly;
|
||
for (size_t j = 0; j < realc[i].size(); j++) {
|
||
poly.emplace_back(realc[i][j].x, realc[i][j].y);
|
||
}
|
||
poly.emplace_back(realc[i][0].x, realc[i][0].y);
|
||
vg->drawLineStrip(poly);
|
||
}
|
||
|
||
vg->setColor(vl::red);
|
||
vg->setLineWidth(2.0f);
|
||
vg->currentEffect()->shader()->disable(vl::EEnable::EN_LINE_SMOOTH);
|
||
for (size_t i = 0; i < m_Solutions.size(); i++) {
|
||
vector<vl::dvec2> poly;
|
||
for (size_t j = 0; j < m_Solutions[i].size(); j++) {
|
||
poly.emplace_back(m_Solutions[i][j].X / CLIPPER_SCALE, m_Solutions[i][j].Y / CLIPPER_SCALE);
|
||
}
|
||
poly.emplace_back(m_Solutions[i][0].X / CLIPPER_SCALE, m_Solutions[i][0].Y / CLIPPER_SCALE);
|
||
vg->drawLineStrip(poly);
|
||
}
|
||
vg->endDrawing();
|
||
}
|
||
LeaveCriticalSection(&cs);
|
||
}
|
||
|
||
std::vector<int> RecoatCheck::GetLayerBorders(MetaData* metadata, unsigned int layer, PolyTree& m_Borders)
|
||
{
|
||
if (metadata == nullptr || layer > metadata->GetLayerCount())
|
||
return vector<int>();
|
||
|
||
MetaData::Layer* player = metadata->GetCurrentLayer();
|
||
if (player == NULL || player->index != layer) {
|
||
if (metadata->LoadLayerByIndex(layer))
|
||
player = metadata->GetCurrentLayer();
|
||
else
|
||
return vector<int>();
|
||
}
|
||
|
||
vector<int> noBorderParts;
|
||
m_Borders.Clear();
|
||
vector<BPBinary::BinDataBlock*> m_BordersDB;
|
||
vector<vector<cv::Point>> m_WorkBorders;
|
||
for (std::map<int, MetaData::DataBlockList*>::iterator it = player->data_blocks_map.begin(); it != player->data_blocks_map.end(); it++) {
|
||
int partid = it->first;
|
||
MetaData::Part* part = metadata->GetPart(partid);
|
||
if (!part->print_enable)
|
||
continue;
|
||
MetaData::DataBlockList* datas = it->second;
|
||
if (datas == NULL)continue;
|
||
|
||
bool noBorder = true;
|
||
for (size_t i = 0; i < datas->size(); ++i) {
|
||
BPBinary::BinDataBlock* pdb = metadata->GetDataBlock((*datas)[i]);
|
||
if (!pdb)break;
|
||
MetaData::ParameterSet* ps = metadata->GetParameterSet((*datas)[i]->references->process);
|
||
if (!ps)continue;
|
||
if (ps->set_type == "Border" || ps->set_type == "BorderUp" || ps->set_type == "BorderDown" ||
|
||
ps->set_type == "InBorder" || ps->set_type == "UpBorder" || ps->set_type == "DownBorder" ||
|
||
ps->set_type == "InBorderJ" || ps->set_type == "DownBorderJ" || ps->set_type == "UpBorderJ") {
|
||
m_BordersDB.push_back(pdb);
|
||
noBorder = false;
|
||
}
|
||
}
|
||
|
||
if (noBorder) {
|
||
noBorderParts.push_back(part->id);
|
||
}
|
||
}
|
||
|
||
PolyTree tmp;
|
||
for (auto db : m_BordersDB) {
|
||
for (size_t i = 0; i < db->point_indexs.size(); i++) {
|
||
BPBinary::ChainPoint* point = (BPBinary::ChainPoint*)db->point_indexs[i];
|
||
PolyNode* poly = new PolyNode;
|
||
for (unsigned int k = 0; k < point->points.size(); ++k) {
|
||
poly->Contour.emplace_back(static_cast<cInt>(point->points[k]->x * CLIPPER_SCALE), static_cast<cInt>(point->points[k]->y * CLIPPER_SCALE));
|
||
}
|
||
|
||
if (poly->Contour.front() == poly->Contour.back()) {
|
||
m_Borders.Childs.push_back(poly);
|
||
m_Borders.AllNodes.push_back(poly);
|
||
}
|
||
else {
|
||
tmp.Childs.push_back(poly);
|
||
}
|
||
}
|
||
}
|
||
|
||
#if 0
|
||
for (int i = 0; i < tmp.ChildCount(); i++) {
|
||
char buf[1024];
|
||
sprintf_s(buf, "#index:%d, cnt:%zd\n", i, tmp.Childs[i]->Contour.size());
|
||
OutputDebugStringA(buf);
|
||
for (size_t j = 0; j < tmp.Childs[i]->Contour.size(); j++) {
|
||
memset(buf, '\0', 1024);
|
||
sprintf_s(buf, "%.10f, %.10f\n", tmp.Childs[i]->Contour[j].X / CLIPPER_SCALE, tmp.Childs[i]->Contour[j].Y / CLIPPER_SCALE);
|
||
OutputDebugStringA(buf);
|
||
}
|
||
OutputDebugStringA("\n\n");
|
||
}
|
||
#endif
|
||
|
||
while (tmp.ChildCount() > 0) {
|
||
PolyNode* closed = tmp.Childs.front();
|
||
tmp.Childs.erase(tmp.Childs.begin());
|
||
|
||
while (closed->Contour.front() != closed->Contour.back()) {
|
||
bool poly_found = false;
|
||
for (int i = 0; i < tmp.ChildCount(); i++) {
|
||
Path& contour = tmp.Childs[i]->Contour;
|
||
if (closed->Contour.back() == contour.front()) {
|
||
closed->Contour.insert(closed->Contour.end(), contour.begin(), contour.end());
|
||
PolyNode* poly = tmp.Childs[i];
|
||
tmp.Childs.erase(tmp.Childs.begin() + i);
|
||
delete poly;
|
||
poly_found = true;
|
||
break;
|
||
}
|
||
else if (closed->Contour.back() == contour.back()) {
|
||
reverse(contour.begin(), contour.end());
|
||
closed->Contour.insert(closed->Contour.end(), contour.begin(), contour.end());
|
||
PolyNode* poly = tmp.Childs[i];
|
||
tmp.Childs.erase(tmp.Childs.begin() + i);
|
||
delete poly;
|
||
poly_found = true;
|
||
break;
|
||
}
|
||
else if (isBetween(contour[0], contour[1], closed->Contour.back())) {
|
||
if (contour.size() == 2) {
|
||
if (isBetween(closed->Contour.back(), closed->Contour[closed->Contour.size() - 2], contour[0])) {
|
||
closed->Contour.push_back(contour[1]);
|
||
}
|
||
else {
|
||
closed->Contour.push_back(contour[0]);
|
||
}
|
||
}
|
||
else {
|
||
closed->Contour.insert(closed->Contour.end(), contour.begin() + 1, contour.end());
|
||
}
|
||
PolyNode* poly = tmp.Childs[i];
|
||
tmp.Childs.erase(tmp.Childs.begin() + i);
|
||
delete poly;
|
||
poly_found = true;
|
||
break;
|
||
}
|
||
else if (isBetween(contour.back(), contour[contour.size() - 2], closed->Contour.back())) {
|
||
if (isBetween(closed->Contour.back(), closed->Contour[closed->Contour.size() - 2], contour.back())/* ||
|
||
isBetween(contour.back(), contour[contour.size() - 2], closed->Contour[closed->Contour.size() - 2])*/) {
|
||
reverse(contour.begin(), contour.end());
|
||
closed->Contour.insert(closed->Contour.end(), contour.begin() + 1, contour.end());
|
||
}
|
||
else {
|
||
closed->Contour.push_back(contour.back());
|
||
}
|
||
PolyNode* poly = tmp.Childs[i];
|
||
tmp.Childs.erase(tmp.Childs.begin() + i);
|
||
delete poly;
|
||
poly_found = true;
|
||
break;
|
||
}
|
||
else {
|
||
for (size_t j = 0; j < 10 && j < contour.size() - 1; j++) {
|
||
if (isBetween(contour[j], contour[j + 1], closed->Contour.back())) {
|
||
if (!isBetween(closed->Contour.back(), closed->Contour[closed->Contour.size() - 2], contour[j + 1]) ||
|
||
!isBetween(contour[j], contour[j + 1], closed->Contour[closed->Contour.size() - 2])) {
|
||
closed->Contour.insert(closed->Contour.end(), contour.begin() + j + 1, contour.end());
|
||
}
|
||
else {
|
||
reverse(contour.begin(), contour.end());
|
||
closed->Contour.insert(closed->Contour.end(), contour.begin() + (contour.size() - j - 1), contour.end());
|
||
}
|
||
|
||
PolyNode* poly = tmp.Childs[i];
|
||
tmp.Childs.erase(tmp.Childs.begin() + i);
|
||
delete poly;
|
||
poly_found = true;
|
||
break;
|
||
}
|
||
}
|
||
if (poly_found)
|
||
break;
|
||
int end_idx = contour.size() - 1;
|
||
for (size_t j = 0; j < 10 && j < contour.size() - 1; j++) {
|
||
if (isBetween(contour[end_idx - j], contour[end_idx - j - 1], closed->Contour.back())) {
|
||
if (!isBetween(closed->Contour.back(), closed->Contour[closed->Contour.size() - 2], contour[end_idx - j - 1]) ||
|
||
!isBetween(contour[end_idx - j], contour[end_idx - j - 1], closed->Contour[closed->Contour.size() - 2])) {
|
||
reverse(contour.begin(), contour.end());
|
||
closed->Contour.insert(closed->Contour.end(), contour.begin() + j + 1, contour.end());
|
||
}
|
||
else {
|
||
closed->Contour.insert(closed->Contour.end(), contour.begin() + (contour.size() - j - 1), contour.end());
|
||
}
|
||
|
||
PolyNode* poly = tmp.Childs[i];
|
||
tmp.Childs.erase(tmp.Childs.begin() + i);
|
||
delete poly;
|
||
poly_found = true;
|
||
break;
|
||
}
|
||
}
|
||
if (poly_found)
|
||
break;
|
||
for (size_t j = 0; j < contour.size() - 1; j++) {
|
||
if (isBetween(contour[j], contour[j + 1], closed->Contour.back())) {
|
||
if (!isBetween(closed->Contour.back(), closed->Contour[closed->Contour.size() - 2], contour[j + 1]) ||
|
||
!isBetween(contour[j], contour[j + 1], closed->Contour[closed->Contour.size() - 2])) {
|
||
closed->Contour.insert(closed->Contour.end(), contour.begin() + j + 1, contour.end());
|
||
}
|
||
else {
|
||
reverse(contour.begin(), contour.end());
|
||
closed->Contour.insert(closed->Contour.end(), contour.begin() + (contour.size() - j - 1), contour.end());
|
||
}
|
||
|
||
PolyNode* poly = tmp.Childs[i];
|
||
tmp.Childs.erase(tmp.Childs.begin() + i);
|
||
delete poly;
|
||
poly_found = true;
|
||
break;
|
||
}
|
||
}
|
||
if (poly_found)
|
||
break;
|
||
}
|
||
}
|
||
if (!poly_found)
|
||
break;
|
||
}
|
||
|
||
if (closed->Contour.front() == closed->Contour.back()) {
|
||
m_Borders.AllNodes.push_back(closed);
|
||
m_Borders.Childs.push_back(closed);
|
||
}
|
||
else {
|
||
bool connected = false;
|
||
for (size_t j = 0; j < 10 && j < closed->Contour.size() - 1; j++) {
|
||
if (isBetween(closed->Contour[j], closed->Contour[j + 1], closed->Contour.back())) {
|
||
closed->Contour.erase(closed->Contour.begin(), closed->Contour.begin() + j);
|
||
m_Borders.AllNodes.push_back(closed);
|
||
m_Borders.Childs.push_back(closed);
|
||
connected = true;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (!connected) {
|
||
closed->Contour.push_back(closed->Contour.front());
|
||
m_Borders.AllNodes.push_back(closed);
|
||
m_Borders.Childs.push_back(closed);
|
||
}
|
||
}
|
||
}
|
||
|
||
BuildTree(&m_Borders);
|
||
|
||
return noBorderParts;
|
||
}
|
||
|
||
bool RecoatCheck::RecoatCheckByContoursIntersect(PolyTree& borders, vector<vector<cv::Point2f>>& uncover, MetaData* metadata)
|
||
{
|
||
RecoatCheckCfg* rcc = ConfigManager::GetInstance()->GetRecoatCheckCfg();
|
||
float xmin = FLT_MAX, xmax = -FLT_MAX, ymin = FLT_MAX, ymax = -FLT_MAX;
|
||
MetaData::JobDimensions* dim = metadata->GetJobDimensions();
|
||
|
||
if (uncover.size() == 0)
|
||
return true;
|
||
|
||
if (!metadata)
|
||
return true;
|
||
|
||
Paths uncovers, untmp;
|
||
for (size_t i = 0; i < uncover.size(); i++) {
|
||
Path tmp;
|
||
for (size_t j = 0; j < uncover[i].size(); j++) {
|
||
tmp.emplace_back(uncover[i][j].x * CLIPPER_SCALE, uncover[i][j].y * CLIPPER_SCALE);
|
||
xmin = std::min(xmin, uncover[i][j].x);
|
||
xmax = std::max(xmax, uncover[i][j].x);
|
||
ymin = std::min(ymin, uncover[i][j].y);
|
||
ymax = std::max(ymax, uncover[i][j].y);
|
||
}
|
||
// make sure it is closed
|
||
tmp.emplace_back(uncover[i][0].x * CLIPPER_SCALE, uncover[i][0].y * CLIPPER_SCALE);
|
||
|
||
// ɸѡ<C9B8><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD>
|
||
if (xmax < dim->xmin || xmin > dim->xmax || ymin > dim->ymax || ymax < dim->ymin)
|
||
continue;
|
||
|
||
untmp.push_back(tmp);
|
||
}
|
||
|
||
SimplifyPolygons(untmp, uncovers);
|
||
|
||
//double thick = *metadata->GetLayerThickness();
|
||
double AreaThreshold = rcc->m_AreaThresholdFactor * CLIPPER_SCALE * CLIPPER_SCALE;
|
||
double LenThreshold = rcc->m_LengthThresholdFactor * CLIPPER_SCALE;
|
||
for (int i = 0; i < borders.ChildCount(); i++) {
|
||
Paths solutions, tmp;
|
||
Clipper clp;
|
||
//EnterCriticalSection(&cs);
|
||
//clp.AddPath(borders.Childs[i]->Contour, ptClip, true);
|
||
tmp.push_back(borders.Childs[i]->Contour);
|
||
for (int j = 0; j < borders.Childs[i]->ChildCount(); j++) {
|
||
//clp.AddPath(borders.Childs[i]->Childs[j]->Contour, ptClip, true);
|
||
tmp.push_back(borders.Childs[i]->Childs[j]->Contour);
|
||
}
|
||
//CleanPolygons(tmp);
|
||
SimplifyPolygons(tmp);
|
||
//m_Solutions.insert(m_Solutions.end(), tmp.begin(), tmp.end());
|
||
//LeaveCriticalSection(&cs);
|
||
clp.AddPaths(tmp, ptClip, true);
|
||
clp.AddPaths(uncovers, ptSubject, true);
|
||
clp.Execute(ctIntersection, solutions);
|
||
EnterCriticalSection(&cs);
|
||
m_Solutions.insert(m_Solutions.begin(), solutions.begin(), solutions.end());
|
||
LeaveCriticalSection(&cs);
|
||
|
||
if (solutions.size() > rcc->m_PerIslandCntThreshold)
|
||
return false;
|
||
|
||
if (solutions.size() > 0) {
|
||
for (size_t i = 0; i < solutions.size(); i++) {
|
||
double tmp = Area(solutions[i]);
|
||
if (tmp > AreaThreshold)
|
||
return false;
|
||
|
||
if (Len(solutions[i]) > LenThreshold)
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
double RecoatCheck::Len(Path& p)
|
||
{
|
||
double len = 0;
|
||
|
||
if (p.size() < 2)
|
||
return 0;
|
||
|
||
for (size_t i = 0; i < p.size() - 1; i++) {
|
||
double tt = (p[i].X - p[i + 1].X) * (p[i].X - p[i + 1].X) + (p[i].Y - p[i + 1].Y) * (p[i].Y - p[i + 1].Y);
|
||
len += sqrt((tt < 0.0) ? 0.0 : tt);
|
||
}
|
||
double tp = (p[0].X - p.back().X) * (p[0].X - p.back().X) + (p[0].Y - p.back().Y) * (p[0].Y - p.back().Y);
|
||
len += sqrt((tp < 0.0) ? 0.0 : tp);
|
||
|
||
return len;
|
||
}
|
||
|
||
void RecoatCheck::BuildTree(PolyTree* node)
|
||
{
|
||
if (node->ChildCount() < 2)
|
||
return;
|
||
|
||
for (int i = 0; i < node->ChildCount(); i++)
|
||
node->Childs[i]->CalcBounds();
|
||
|
||
unsigned int max_level = 0;
|
||
for (int i = 0; i < node->ChildCount(); i++) {
|
||
ClipperLib::PolyNode* p0 = node->Childs[i];
|
||
for (int j = 0; j < node->ChildCount(); j++) {
|
||
if (j == i)
|
||
continue;
|
||
|
||
ClipperLib::PolyNode* p1 = node->Childs[j];
|
||
if (p1->IsInside(p0)) {
|
||
p1->depth++;
|
||
if (p1->depth > max_level)
|
||
max_level = p1->depth;
|
||
}
|
||
}
|
||
}
|
||
|
||
vector<PolyNode*> childs_copy;
|
||
childs_copy.insert(childs_copy.begin(), node->Childs.begin(), node->Childs.end());
|
||
|
||
for (unsigned int i = 1; i <= max_level; i += 2) {
|
||
for (size_t j = 0; j < childs_copy.size(); j++) {
|
||
if (childs_copy[j]->depth != i)
|
||
continue;
|
||
PolyNode* pj = childs_copy[j];
|
||
if (Orientation(pj->Contour))
|
||
ReversePath(pj->Contour);
|
||
for (size_t k = 0; k < childs_copy.size(); k++) {
|
||
if (childs_copy[k]->depth != i - 1)
|
||
continue;
|
||
PolyNode* pk = childs_copy[k];
|
||
if (!Orientation(pk->Contour))
|
||
ReversePath(pk->Contour);
|
||
if (pj->IsInside(pk)) {
|
||
if (node->ChildCount() > 0) {
|
||
vector<PolyNode*>::iterator it = node->Childs.begin();
|
||
for (; it != node->Childs.end(); it++) {
|
||
if (*it == pj) {
|
||
node->Childs.erase(it);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
pj->Parent = pk;
|
||
pk->Childs.push_back(pj);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
for (PolyNode* poly : node->Childs) {
|
||
if (poly->ChildCount() == 0 && !Orientation(poly->Contour))
|
||
ReversePath(poly->Contour);
|
||
}
|
||
|
||
double* bounds = node->GetBounds();
|
||
for (PolyNode* poly : node->AllNodes) {
|
||
bounds[0] = std::min(bounds[0], poly->GetBounds()[0]);
|
||
bounds[1] = std::max(bounds[1], poly->GetBounds()[1]);
|
||
bounds[2] = std::min(bounds[2], poly->GetBounds()[2]);
|
||
bounds[3] = std::max(bounds[3], poly->GetBounds()[3]);
|
||
}
|
||
}
|
||
|
||
bool RecoatCheck::isBetween(IntPoint a, IntPoint b, IntPoint c)
|
||
{
|
||
double ax = a.X * 1.0e-9;
|
||
double ay = a.Y * 1.0e-9;
|
||
double bx = b.X * 1.0e-9;
|
||
double by = b.Y * 1.0e-9;
|
||
double cx = c.X * 1.0e-9;
|
||
double cy = c.Y * 1.0e-9;
|
||
|
||
double actemp = ((cx - ax) * (cx - ax) + (cy - ay) * (cy - ay));
|
||
double bctemp = (cx - bx) * (cx - bx) + (cy - by) * (cy - by);
|
||
double abtemp = (ax - bx) * (ax - bx) + (ay - by) * (ay - by);
|
||
|
||
double ac = sqrt((actemp < 0.0f) ? 0.0f : actemp);
|
||
double bc = sqrt((bctemp < 0.0f) ? 0.0f : bctemp);
|
||
double ab = sqrt((abtemp < 0.0f) ? 0.0f : abtemp);
|
||
|
||
double delta = abs(ab - (ac + bc));
|
||
|
||
return delta < 1.0e-9;
|
||
|
||
#if 0
|
||
// if AC is vertical
|
||
if (a.X == c.X) return b.X == c.X;
|
||
// if AC is horizontal
|
||
if (a.Y == c.Y) return b.Y == c.Y;
|
||
// match the gradients
|
||
return (a.X - c.X) * (a.Y - c.Y) == (c.X - b.X) * (c.Y - b.Y);
|
||
#if 0
|
||
if (a == c || b == c)
|
||
return true;
|
||
#endif
|
||
|
||
cInt crossproduct = (c.Y - a.Y) * (b.X - a.X) - (c.X - a.X) * (b.Y - a.Y);
|
||
|
||
// compare versus epsilon for floating point values, or != 0 if using integers
|
||
double tmp = abs(crossproduct * 1.0e-18);
|
||
if (tmp > 2.0e-3)
|
||
return false;
|
||
|
||
cInt dotproduct = (c.X - a.X) * (b.X - a.X) + (c.Y - a.Y) * (b.Y - a.Y);
|
||
double ddotproduct = dotproduct * 1.0e-18;
|
||
if (ddotproduct < 0)
|
||
return false;
|
||
|
||
cInt squaredlengthba = (b.X - a.X) * (b.X - a.X) + (b.Y - a.Y) * (b.Y - a.Y);
|
||
double dsquaredlengthba = squaredlengthba * 1.0e-18;
|
||
if (ddotproduct > dsquaredlengthba)
|
||
return false;
|
||
|
||
return true;
|
||
#endif
|
||
}
|
||
|
||
double RecoatCheck::Dist(IntPoint a, IntPoint b)
|
||
{
|
||
double tt = (a.X / CLIPPER_SCALE - b.X / CLIPPER_SCALE) * (a.X / CLIPPER_SCALE - b.X / CLIPPER_SCALE) +
|
||
(a.Y / CLIPPER_SCALE - b.Y / CLIPPER_SCALE) * (a.Y / CLIPPER_SCALE - b.Y / CLIPPER_SCALE);
|
||
double tmp = sqrt((tt < 0.0) ? 0.0 : tt);
|
||
return tmp;
|
||
}
|
||
|
||
|
||
//void RecoatCheck::DrawStatus(bool* isShow)
|
||
//{
|
||
// if (!*isShow) {
|
||
// isNeedDisp = false;
|
||
// if (m_DispTex > 0) {
|
||
// glDeleteTextures(1, &m_DispTex);
|
||
// m_DispTex = 0;
|
||
// }
|
||
// return;
|
||
// }
|
||
//
|
||
// isNeedDisp = true;
|
||
// ImGui::Begin(g_LngManager->Cfg_RecoatCheckConfig->ShowText(), isShow, ImGuiWindowFlags_NoDocking);
|
||
// //if (ImGui::IsWindowAppearing())
|
||
// // isNeedDisp = true;
|
||
//
|
||
// //if (ImGui::Button("Test")) {
|
||
// // Check(nullptr, 0, nullptr, 0, 0);
|
||
// //}
|
||
// EnterCriticalSection(&disp_cs);
|
||
// if (isDispUpdated) {
|
||
// isDispUpdated = false;
|
||
// if (m_DispTex == 0) {
|
||
// glGenTextures(1, &m_DispTex);
|
||
// glBindTexture(GL_TEXTURE_2D, m_DispTex);
|
||
// glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||
// glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, m_DstWidth, m_DstHeight, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, m_WarpDst.data);
|
||
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||
// glBindTexture(GL_TEXTURE_2D, 0);
|
||
// }
|
||
// else {
|
||
// glBindTexture(GL_TEXTURE_2D, m_DispTex);
|
||
// glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||
// glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_DstWidth, m_DstHeight, GL_LUMINANCE, GL_UNSIGNED_BYTE, m_WarpDst.data);
|
||
// glBindTexture(GL_TEXTURE_2D, 0);
|
||
// }
|
||
// }
|
||
// LeaveCriticalSection(&disp_cs);
|
||
//
|
||
// ImGui::Image((ImTextureID)m_DispTex, ImVec2(600, 600));
|
||
// ImGui::End();
|
||
//}
|
||
|
||
|
||
bool RecoatCheck::CheckWP(MetaData* metadata, unsigned int layer, unsigned char** img, int width, int high)
|
||
{
|
||
MachineCfg* mcfg = ConfigManager::GetInstance()->GetMachineCfg();
|
||
RecoatCheckCfg* rcc = ConfigManager::GetInstance()->GetRecoatCheckCfg();
|
||
if (!rcc->m_Enable)
|
||
return true;
|
||
|
||
if (!img || width <= 0 || high <= 0)
|
||
return true;
|
||
|
||
cv::Mat image(high, width, CV_8U, *img);
|
||
switch (m_ExtCfg->m_ShowImageRotateAngle)
|
||
{
|
||
case ExtCfg::Angle_0: {
|
||
}break;
|
||
case ExtCfg::Angle_90: {
|
||
cv::rotate(image, image, cv::ROTATE_90_COUNTERCLOCKWISE);
|
||
}break;
|
||
case ExtCfg::Angle_180: {
|
||
cv::rotate(image, image, cv::ROTATE_180);
|
||
}break;
|
||
case ExtCfg::Angle_270: {
|
||
cv::rotate(image, image, cv::ROTATE_90_CLOCKWISE);
|
||
}break;
|
||
}
|
||
|
||
cv::Mat mask = cv::Mat::zeros(image.size(), image.type());
|
||
vector<vector<cv::Point>> contour;
|
||
vector<cv::Point> pts;
|
||
pts.push_back(cv::Point(rcc->m_MaskTopLeftX, rcc->m_MaskTopLeftY));
|
||
pts.push_back(cv::Point(rcc->m_MaskTopRightX, rcc->m_MaskTopRightY));
|
||
pts.push_back(cv::Point(rcc->m_MaskBottomRightX, rcc->m_MaskBottomRightY));
|
||
pts.push_back(cv::Point(rcc->m_MaskBottomLeftX, rcc->m_MaskBottomLeftY));
|
||
pts.push_back(cv::Point(rcc->m_MaskTopLeftX, rcc->m_MaskTopLeftY));
|
||
contour.push_back(pts);
|
||
drawContours(mask, contour, 0, cv::Scalar::all(255), -1);
|
||
|
||
unsigned char lut[256];
|
||
double gamma = 0.5;
|
||
for (int i = 0; i < 256; i++)
|
||
{
|
||
lut[i] = cv::saturate_cast<uchar>(pow((float)i / 255.0, gamma) * 255.0f);
|
||
}
|
||
|
||
|
||
cv::MatIterator_<uchar> it = image.begin<uchar>();
|
||
cv::MatIterator_<uchar> end = image.end<uchar>();
|
||
while (it != end)
|
||
{
|
||
*it = lut[(*it)];
|
||
it++;
|
||
}
|
||
//imwrite("g:/testimage/ffc0.bmp", image);
|
||
//Mat bg;
|
||
//GaussianBlur(image, bg, Size(201, 201), 100);
|
||
//Scalar m = mean(image);
|
||
//divide(image, bg, image, m.val[0]);
|
||
//equalizeHist(image, image);
|
||
bitwise_and(image, mask, image);
|
||
// imwrite("g:/testimage/ffc1.bmp", image);
|
||
|
||
cv::Point2f srcTri[4];
|
||
srcTri[0] = cv::Point2f(rcc->m_MaskTopLeftX, rcc->m_MaskTopLeftY);
|
||
srcTri[1] = cv::Point2f(rcc->m_MaskTopRightX, rcc->m_MaskTopRightY);
|
||
srcTri[2] = cv::Point2f(rcc->m_MaskBottomRightX, rcc->m_MaskBottomRightY);
|
||
srcTri[3] = cv::Point2f(rcc->m_MaskBottomLeftX, rcc->m_MaskBottomLeftY);
|
||
|
||
|
||
cv::Point2f tempTri[4], dstTri[4];
|
||
// Mat warp_mat = getPerspectiveTransform(srcTri, dstTri);
|
||
float plr = (float)mcfg->m_PlatformLength->GetValue() / mcfg->m_PlatformWidth->GetValue();
|
||
int wwidth = 1000;
|
||
int wheight = 1000.0f / plr;
|
||
float wr = 1000.0 / mcfg->m_PlatformLength->GetValue();
|
||
float wh = (float)wheight / mcfg->m_PlatformWidth->GetValue();
|
||
tempTri[0] = cv::Point2f(0.0f, 0.0f);
|
||
tempTri[1] = cv::Point2f(wwidth, 0.0f);
|
||
tempTri[2] = cv::Point2f(wwidth, wheight);
|
||
tempTri[3] = cv::Point2f(0.0f, wheight);
|
||
|
||
cv::Mat warp_mat = getPerspectiveTransform(srcTri, tempTri);
|
||
|
||
|
||
dstTri[0] = cv::Point2f(0.f, 0.f);
|
||
dstTri[1] = cv::Point2f(m_DstWidth, 0.f);
|
||
dstTri[2] = cv::Point2f(m_DstWidth, m_DstHeight);
|
||
dstTri[3] = cv::Point2f(0.0f, m_DstHeight);
|
||
cv::Mat disp_warp_mat = getPerspectiveTransform(tempTri, dstTri);
|
||
|
||
|
||
cv::Mat imageTemp(cv::Size(wwidth, wheight), CV_8U);
|
||
warpPerspective(image, imageTemp, warp_mat, imageTemp.size());
|
||
//imwrite("g:/testimage/ffc3.bmp", imageTemp);
|
||
cv::Mat laws_mask = generateMask2D(allMasks, 1, 0);
|
||
//boxFilter(loc, loc,-1, Size(3, 3));
|
||
//imwrite("g:/testimage/ffc2-1.bmp", loc);
|
||
//equalizeHist(imageTemp, imageTemp);
|
||
//imwrite("g:/testimage/ffc2-1.bmp", imageTemp);
|
||
/*Mat imageTemp2(Size(wwidth, wheight), CV_8U);
|
||
for (int i = 0; i < imageTemp.rows; i++)
|
||
{
|
||
for (int j = 0; j < imageTemp.cols; j++)
|
||
{
|
||
imageTemp2.at<unsigned char>(i, j) = log(1 + imageTemp.at<unsigned char>(i, j));
|
||
}
|
||
}
|
||
normalize(imageTemp2, imageTemp2, 0, 255, NORM_MINMAX);*/
|
||
//imwrite("g:/testimage/ffc3.bmp", imageTemp);
|
||
//GaussianBlur(imageLog, imageLog, Size(5, 5), 0, 0);
|
||
cv::Mat dst;
|
||
//blur(imageTemp, dst, Size(3, 3));
|
||
cv::boxFilter(imageTemp, dst, -1, cv::Size(3, 3));
|
||
//
|
||
//boxFilter(imageTemp, dst,-1, Size(3, 3));
|
||
//imwrite("g:/testimage/ffc3-1.bmp", dst);
|
||
//Mat element = getStructuringElement(MORPH_RECT, Size(5, 5));
|
||
//morphologyEx(imageTemp, dst, MORPH_CLOSE, element);
|
||
//blur(dst, dst, Size(3, 3));
|
||
//filter2D(dst, dst, -1, laws_mask);
|
||
//blur(dst, dst, Size(7, 7));
|
||
//imwrite("g:/testimage/ffc4.bmp", imageTemp);
|
||
cv::Mat mat_mean, mat_stddev;
|
||
double avg = 0.0, sd = 0.0;
|
||
cv::Mat upPart(cv::Size(dst.size().width, dst.size().height / 2), CV_8U);
|
||
if (rcc->m_IsUpPartNotLight) {
|
||
for (int i = 0; i < upPart.rows; i++) {
|
||
for (int j = 0; j < upPart.cols; j++) {
|
||
upPart.at<unsigned char>(i, j) = dst.at<unsigned char>(i, j);
|
||
}
|
||
}
|
||
//GaussianBlur(upPart, upPart, Size(5, 5), 0, 0);
|
||
cv::filter2D(upPart, upPart, -1, laws_mask);
|
||
cv::blur(upPart, upPart, cv::Size(7, 7));
|
||
cv::Mat element = getStructuringElement(cv::MORPH_RECT, cv::Size(8, 8));
|
||
morphologyEx(upPart, upPart, cv::MORPH_CLOSE, element);
|
||
|
||
morphologyEx(upPart, upPart, cv::MORPH_OPEN, element);
|
||
//imwrite("g:/testimage/ffc3-2.bmp", upPart);
|
||
|
||
meanStdDev(upPart, mat_mean, mat_stddev);
|
||
avg = mat_mean.at<double>(0, 0);
|
||
sd = mat_stddev.at<double>(0, 0);
|
||
int bt = avg + sd + 10;
|
||
if (bt > 200)bt = 200;
|
||
if (bt < rcc->m_BinaryThreshold)bt = rcc->m_BinaryThreshold;
|
||
threshold(upPart, upPart, bt, 255, cv::ThresholdTypes::THRESH_BINARY);
|
||
}
|
||
cv::Mat element = getStructuringElement(cv::MORPH_RECT, cv::Size(8, 8));
|
||
morphologyEx(dst, dst, cv::MORPH_CLOSE, element);
|
||
//imwrite("g:/testimage/ffc4.bmp", upPart);
|
||
|
||
meanStdDev(dst, mat_mean, mat_stddev);
|
||
avg = mat_mean.at<double>(0, 0);
|
||
sd = mat_stddev.at<double>(0, 0);
|
||
int bt = avg + sd + 20;
|
||
if (bt > 200)bt = 200;
|
||
if (bt < rcc->m_BinaryThreshold)bt = rcc->m_BinaryThreshold;
|
||
threshold(dst, dst, bt, 255, cv::ThresholdTypes::THRESH_BINARY);
|
||
|
||
if (rcc->m_IsUpPartNotLight) {
|
||
for (int i = 0; i < upPart.rows; i++) {
|
||
for (int j = 0; j < upPart.cols; j++) {
|
||
dst.at<unsigned char>(i, j) = upPart.at<unsigned char>(i, j);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
//filter2D(dst, dst, -1, laws_mask);
|
||
//imwrite("g:/testimage/ffc4-1.bmp", dst);
|
||
|
||
//imwrite("g:/testimage/ffc4-1.bmp", dst);
|
||
//s = s < 130 ? s + 40 : s;
|
||
//Mat imageTemp2(dst.size(), CV_8U);
|
||
|
||
//threshold(dst, dst, avg+sd, 255, ThresholdTypes::THRESH_BINARY);
|
||
//threshold(dst, dst, rcc->m_BinaryThreshold, 255, ThresholdTypes::THRESH_BINARY);
|
||
//imwrite("g:/testimage/ffc5.bmp", dst);
|
||
//if (isNeedDisp) {
|
||
EnterCriticalSection(&disp_cs);
|
||
vector<vector<cv::Point>> disp_contours;
|
||
vector<cv::Vec4i> disp_hierarchy;
|
||
findContours(dst, disp_contours, disp_hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_NONE, cv::Point());
|
||
//warpPerspective(image, warp_dst, disp_warp_mat, warp_dst.size());
|
||
drawContours(imageTemp, disp_contours, -1, cv::Scalar(255), 2);
|
||
warpPerspective(imageTemp, m_WarpDst, disp_warp_mat, m_WarpDst.size());
|
||
isDispUpdated = true;
|
||
LeaveCriticalSection(&disp_cs);
|
||
//}
|
||
|
||
if (metadata && layer > 0) {
|
||
|
||
if (metadata == nullptr || layer > metadata->GetLayerCount())return true;
|
||
MetaData::Layer* player = metadata->GetCurrentLayer();
|
||
if (player == NULL || player->index != layer) {
|
||
if (metadata->LoadLayerByIndex(layer))
|
||
player = metadata->GetCurrentLayer();
|
||
else
|
||
return true;
|
||
}
|
||
|
||
float halfWidth = (float)mcfg->m_PlatformLength->GetValue() / 2.0f;
|
||
float halfHigh = (float)mcfg->m_PlatformWidth->GetValue() / 2.0f;
|
||
|
||
|
||
//imwrite("g:/testimage/ffc8.bmp", dataimg);
|
||
vector<cv::Vec4i> disp_hierarchy;
|
||
vector<vector<cv::Point>> disp_contours;
|
||
MetaData::JobDimensions* dim = metadata->GetJobDimensions();
|
||
int xmin_m2 = (halfWidth + dim->xmin) * wr;
|
||
int xmax_m2 = (halfWidth + dim->xmax) * wr;
|
||
int ymin_m2 = (halfHigh - dim->ymax) * wh;
|
||
int ymax_m2 = (halfHigh - dim->ymin) * wh;
|
||
|
||
|
||
cv::Mat mask2 = cv::Mat::zeros(dst.size(), dst.type());
|
||
vector<vector<cv::Point>> contour2;
|
||
vector<cv::Point> pts2;
|
||
pts2.push_back(cv::Point(xmin_m2, ymin_m2));
|
||
pts2.push_back(cv::Point(xmax_m2, ymin_m2));
|
||
pts2.push_back(cv::Point(xmax_m2, ymax_m2));
|
||
pts2.push_back(cv::Point(xmin_m2, ymax_m2));
|
||
pts2.push_back(cv::Point(xmin_m2, ymin_m2));
|
||
contour2.push_back(pts2);
|
||
drawContours(mask2, contour2, 0, cv::Scalar::all(255), -1);
|
||
//imwrite("g:/testimage/ffc9.bmp", mask2);
|
||
bitwise_and(dst, mask2, dst);
|
||
mask2.release();
|
||
//imwrite("g:/testimage/ffc9-1.bmp", dst);
|
||
findContours(dst, disp_contours, disp_hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_NONE);
|
||
double area = 0.0f;
|
||
for (size_t i = 0; i < disp_contours.size(); i++) {
|
||
area += contourArea(disp_contours[i]);
|
||
}
|
||
//drawContours(imageTemp, disp_contours, -1, Scalar(100), 2);
|
||
//imwrite("g:/testimage/ffc9-1.bmp", imageTemp);
|
||
|
||
float dotWidth = 0.0f;
|
||
vector<BPBinary::BinDataBlock*> m_HatchingDB;
|
||
vector<BPBinary::BinDataBlock*> m_SupportDB;
|
||
metadata->LockMainDB();
|
||
for (std::map<int, MetaData::DataBlockList*>::iterator it = player->data_blocks_map.begin(); it != player->data_blocks_map.end(); it++) {
|
||
int partid = it->first;
|
||
MetaData::Part* part = metadata->GetPart(partid);
|
||
if (!part->print_enable)
|
||
continue;
|
||
MetaData::DataBlockList* datas = it->second;
|
||
if (datas == NULL)continue;
|
||
|
||
for (unsigned int i = 0; i < datas->size(); ++i) {
|
||
BPBinary::BinDataBlock* pdb = metadata->GetDataBlock((*datas)[i]);
|
||
if (!pdb)break;
|
||
MetaData::ParameterSet* ps = metadata->GetParameterSet((*datas)[i]->references->process);
|
||
if (!ps) {
|
||
continue;
|
||
}
|
||
|
||
if (ps->set_type.find("Hatching") != ps->set_type.npos)
|
||
{
|
||
if (pdb->type == BIN_VECTOR) {
|
||
m_HatchingDB.push_back(pdb);
|
||
}
|
||
|
||
}
|
||
else if (ps->set_type.find("Support") != ps->set_type.npos) {
|
||
m_SupportDB.push_back(pdb);
|
||
}
|
||
|
||
|
||
}
|
||
}
|
||
|
||
int calcCount = 0;
|
||
vector<CalcVar> calcV;
|
||
float AreaSum = 0.0f;
|
||
for (size_t i = 0; i < m_HatchingDB.size(); i++) {
|
||
for (size_t j = 0; j < m_HatchingDB[i]->point_indexs.size(); ++j) {
|
||
BPBinary::VectorPoint* pvp = (BPBinary::VectorPoint*)m_HatchingDB[i]->point_indexs[j];
|
||
CalcVar cv;
|
||
cv.difx = pvp->x2 - pvp->x1;
|
||
cv.dify = pvp->y2 - pvp->y1;
|
||
cv.a = -(pvp->y2 - pvp->y1);
|
||
cv.b = pvp->x2 - pvp->x1;
|
||
cv.c = (pvp->y2 - pvp->y1) * pvp->x1 - (pvp->x2 - pvp->x1) * pvp->y1;
|
||
calcV.push_back(cv);
|
||
calcCount++;
|
||
if (calcCount >= 10)break;
|
||
}
|
||
if (calcCount >= 10)break;
|
||
}
|
||
metadata->UnLockMainDB();
|
||
if (calcV.size() < 10) {
|
||
dotWidth = 1.0f;
|
||
}
|
||
else {
|
||
CalcVar preV = calcV[0];
|
||
float disSum = 0.0f;
|
||
int count = 0;
|
||
float maxcalc = -FLT_MAX;
|
||
float mincalc = FLT_MAX;
|
||
for (size_t i = 1; i < calcV.size(); i++) {
|
||
CalcVar tempV = calcV[i];
|
||
float value = abs((preV.difx * tempV.dify) - (preV.dify * tempV.difx));
|
||
if (value < 0.01f) {
|
||
float calcT = preV.a * preV.a + preV.b * preV.b;
|
||
if (calcT > 0.0f) {
|
||
float calcSqr = sqrt(calcT);
|
||
if (calcSqr != 0.0f) {
|
||
float dis = abs(preV.c - preV.b * tempV.c / tempV.b) / calcSqr;
|
||
disSum += dis;
|
||
count++;
|
||
if (dis > maxcalc)maxcalc = dis;
|
||
if (dis < mincalc)mincalc = dis;
|
||
}
|
||
else {
|
||
preV = tempV;
|
||
continue;
|
||
}
|
||
}
|
||
else {
|
||
preV = tempV;
|
||
continue;
|
||
}
|
||
}
|
||
preV = tempV;
|
||
}
|
||
if (count >= 3) {
|
||
disSum -= maxcalc;
|
||
disSum -= mincalc;
|
||
dotWidth = disSum / (count - 2);
|
||
}
|
||
else {
|
||
dotWidth = 1.0f;
|
||
}
|
||
}
|
||
metadata->LockMainDB();
|
||
for (size_t i = 0; i < m_HatchingDB.size(); i++) {
|
||
for (size_t j = 0; j < m_HatchingDB[i]->point_indexs.size(); ++j) {
|
||
BPBinary::VectorPoint* pvp = (BPBinary::VectorPoint*)m_HatchingDB[i]->point_indexs[j];
|
||
float dsq = (pvp->x1 - pvp->x2) * (pvp->x1 - pvp->x2) + (pvp->y1 - pvp->y2) * (pvp->y1 - pvp->y2);
|
||
if (dsq > 0.0f) {
|
||
float dis = sqrt(dsq);
|
||
AreaSum = AreaSum + (dis * dotWidth);
|
||
}
|
||
}
|
||
}
|
||
for (size_t i = 0; i < m_SupportDB.size(); i++) {
|
||
BPBinary::BinDataBlock* pdb = m_SupportDB[i];
|
||
if (pdb->type == BIN_VECTOR) {
|
||
for (size_t j = 0; j < m_SupportDB[i]->point_indexs.size(); ++j) {
|
||
BPBinary::VectorPoint* pvp = (BPBinary::VectorPoint*)m_SupportDB[i]->point_indexs[j];
|
||
float dsq = (pvp->x1 - pvp->x2) * (pvp->x1 - pvp->x2) + (pvp->y1 - pvp->y2) * (pvp->y1 - pvp->y2);
|
||
if (dsq > 0.0f) {
|
||
float dis = sqrt(dsq);
|
||
AreaSum = AreaSum + (dis * dotWidth);
|
||
}
|
||
}
|
||
}
|
||
else if (pdb->type == BIN_CHAIN) {
|
||
for (unsigned int j = 0; j < pdb->point_indexs.size(); ++j) {
|
||
BPBinary::ChainPoint* point = (BPBinary::ChainPoint*)pdb->point_indexs[j];
|
||
if (point->points.empty())continue;
|
||
float prex = point->points[0]->x;
|
||
float prey = point->points[0]->y;
|
||
for (unsigned int k = 1; k < point->points.size(); ++k) {
|
||
float x = point->points[k]->x;
|
||
float y = point->points[k]->y;
|
||
float dsq = (prex - x) * (prex - x) + (prey - y) * (prey - y);
|
||
if (dsq > 0.0f) {
|
||
float dis = sqrt(dsq);
|
||
AreaSum = AreaSum + (dis * dotWidth);
|
||
}
|
||
prex = x;
|
||
prey = y;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
metadata->UnLockMainDB();
|
||
/*GetLayerBorders(metadata, layer, m_Borders);
|
||
Paths tmp_paths;
|
||
PolyTreeToPaths(m_Borders, tmp_paths);
|
||
ClipperLib::ClipperOffset co;
|
||
co.AddPaths(tmp_paths, ClipperLib::jtMiter, ClipperLib::etClosedPolygon);
|
||
co.MiterLimit = 1.2;
|
||
co.ArcTolerance = 0.25 * CLIPPER_SCALE;
|
||
m_Borders.Clear();
|
||
co.Execute(m_Borders, 0.03 * CLIPPER_SCALE);
|
||
double AreaSum = 0.0f;
|
||
for (PolyNode* pn : m_Borders.AllNodes) {
|
||
AreaSum += Area(pn->Contour);
|
||
}*/
|
||
AreaSum = AreaSum * wh * wr;
|
||
|
||
if (AreaSum == 0.0f) {
|
||
return true;
|
||
}
|
||
|
||
float areaRat = area / AreaSum * 100.0f;
|
||
if (areaRat > rcc->m_UncoverPercentage)
|
||
{
|
||
return false;
|
||
}
|
||
else return true;
|
||
|
||
}
|
||
else return true;
|
||
}
|
||
|
||
bool RecoatCheck::CheckWP2(MetaData* metadata, unsigned int layer)
|
||
{
|
||
MachineCfg* mcfg = ConfigManager::GetInstance()->GetMachineCfg();
|
||
RecoatCheckCfg* rcc = ConfigManager::GetInstance()->GetRecoatCheckCfg();
|
||
if (!rcc->m_Enable)return true;
|
||
if (m_CameraCalibrationCfg->m_CameraMatrix00->GetValue() == 0.0 || !Calibration::m_CoverImage) {
|
||
return true;
|
||
}
|
||
|
||
int width = 0, high = 0, datasize = 0;
|
||
m_Camera->GetOriginSize(width, high, datasize);
|
||
//width = 3840; high = 2748; datasize = width*high;
|
||
if (datasize <= 0 || width <= 0 || high <= 0)return true;
|
||
unsigned char* img = new unsigned char[datasize];
|
||
if (!m_Camera->GetRawImage(img))
|
||
{
|
||
if (img)delete[] img;
|
||
return true;
|
||
}
|
||
cv::Mat image(high, width, CV_8U, img);
|
||
|
||
//cv::Mat image = cv::imread("g:/testimage/1.bmp");
|
||
//cv::cvtColor(image, image, 11);
|
||
|
||
switch (m_ExtCfg->m_ShowImageRotateAngle)
|
||
{
|
||
case ExtCfg::Angle_0: {
|
||
}break;
|
||
case ExtCfg::Angle_90: {
|
||
cv::rotate(image, image, cv::ROTATE_90_COUNTERCLOCKWISE);
|
||
}break;
|
||
case ExtCfg::Angle_180: {
|
||
cv::rotate(image, image, cv::ROTATE_180);
|
||
}break;
|
||
case ExtCfg::Angle_270: {
|
||
cv::rotate(image, image, cv::ROTATE_90_CLOCKWISE);
|
||
}break;
|
||
}
|
||
|
||
//g_log->TraceInfo("divide");
|
||
cv::Mat divImage;
|
||
cv::Scalar partMean = cv::mean(image);
|
||
cv::divide(image, Calibration::m_CoverImage->m_ImageMat, divImage, partMean.val[0]);
|
||
|
||
//image.release();
|
||
//cv::imwrite("g:/testimage/div.bmp", divImage);
|
||
//g_log->TraceInfo("release");
|
||
cv::Mat divImage2;
|
||
cv::Scalar partMean2 = cv::mean(Calibration::m_CoverImage->m_ImageMat);
|
||
cv::divide(Calibration::m_CoverImage->m_ImageMat, Calibration::m_CoverImage->m_ImageMat, divImage2, partMean2.val[0]);
|
||
//cv::imwrite("g:/testimage/cc.bmp", divImage2);
|
||
//g_log->TraceInfo("divide2");
|
||
cv::Mat cameraMatrix = cv::Mat(3, 3, CV_64FC1, cv::Scalar::all(0)); //摄像机内参数矩阵
|
||
cv::Mat distCoeffs = cv::Mat(1, 5, CV_64FC1, cv::Scalar::all(0)); //摄像机的5个畸变系数:k1,k2,p1,p2,k3
|
||
|
||
cameraMatrix.at<double>(0, 0) = m_CameraCalibrationCfg->m_CameraMatrix00->GetValue();
|
||
cameraMatrix.at<double>(0, 1) = m_CameraCalibrationCfg->m_CameraMatrix01->GetValue();
|
||
cameraMatrix.at<double>(0, 2) = m_CameraCalibrationCfg->m_CameraMatrix02->GetValue();
|
||
cameraMatrix.at<double>(1, 0) = m_CameraCalibrationCfg->m_CameraMatrix10->GetValue();
|
||
cameraMatrix.at<double>(1, 1) = m_CameraCalibrationCfg->m_CameraMatrix11->GetValue();
|
||
cameraMatrix.at<double>(1, 2) = m_CameraCalibrationCfg->m_CameraMatrix12->GetValue();
|
||
cameraMatrix.at<double>(2, 0) = m_CameraCalibrationCfg->m_CameraMatrix20->GetValue();
|
||
cameraMatrix.at<double>(2, 1) = m_CameraCalibrationCfg->m_CameraMatrix21->GetValue();
|
||
cameraMatrix.at<double>(2, 2) = m_CameraCalibrationCfg->m_CameraMatrix22->GetValue();
|
||
distCoeffs.at<double>(0, 0) = m_CameraCalibrationCfg->m_DistCoeffs0->GetValue();
|
||
distCoeffs.at<double>(0, 1) = m_CameraCalibrationCfg->m_DistCoeffs1->GetValue();
|
||
distCoeffs.at<double>(0, 2) = m_CameraCalibrationCfg->m_DistCoeffs2->GetValue();
|
||
distCoeffs.at<double>(0, 3) = m_CameraCalibrationCfg->m_DistCoeffs3->GetValue();
|
||
distCoeffs.at<double>(0, 4) = m_CameraCalibrationCfg->m_DistCoeffs4->GetValue();
|
||
cv::Mat calImage;
|
||
undistort(divImage, calImage, cameraMatrix, distCoeffs);
|
||
//g_log->TraceInfo("undistort");
|
||
//cv::imwrite("g:/testimage/cal.bmp", calImage);
|
||
cv::Point2f srcTri[4];
|
||
srcTri[0] = cv::Point2f((float)m_CameraCalibrationCfg->m_ImageTopLeftX->GetValue(), (float)m_CameraCalibrationCfg->m_ImageTopLeftY->GetValue());
|
||
srcTri[1] = cv::Point2f((float)m_CameraCalibrationCfg->m_ImageTopRightX->GetValue(), (float)m_CameraCalibrationCfg->m_ImageTopRightY->GetValue());
|
||
srcTri[2] = cv::Point2f((float)m_CameraCalibrationCfg->m_ImageBottomRightX->GetValue(), (float)m_CameraCalibrationCfg->m_ImageBottomRightY->GetValue());
|
||
srcTri[3] = cv::Point2f((float)m_CameraCalibrationCfg->m_ImageBottomLeftX->GetValue(), (float)m_CameraCalibrationCfg->m_ImageBottomLeftY->GetValue());
|
||
cv::Point2f tempTri[4];
|
||
|
||
int tx = (m_CameraCalibrationCfg->m_PlatformTopRightX->GetValue() - m_CameraCalibrationCfg->m_PlatformTopLeftX->GetValue()) * rcc->m_ImageScale;
|
||
int ty = (m_CameraCalibrationCfg->m_PlatformTopRightY->GetValue() - m_CameraCalibrationCfg->m_PlatformBottomRightY->GetValue()) * rcc->m_ImageScale;
|
||
|
||
tempTri[0] = cv::Point2f(0.0f, 0.0f);
|
||
tempTri[1] = cv::Point2f((float)tx, 0.0f);
|
||
tempTri[2] = cv::Point2f((float)tx, (float)ty);
|
||
tempTri[3] = cv::Point2f(0.0f, (float)ty);
|
||
cv::Mat warp_mat = cv::getPerspectiveTransform(srcTri, tempTri);
|
||
cv::Mat wm(cv::Size(tx, ty), CV_8U);
|
||
cv::Mat bgFix(cv::Size(tx, ty), CV_8U);
|
||
warpPerspective(calImage, wm, warp_mat, wm.size());
|
||
//cv::imwrite("g:/testimage/war.bmp", wm);
|
||
warpPerspective(divImage2, bgFix, warp_mat, bgFix.size());
|
||
|
||
//g_log->TraceInfo("warpPerspective");
|
||
|
||
cv::Mat bg_mean, bg_stddev;
|
||
cv::meanStdDev(bgFix, bg_mean, bg_stddev);
|
||
double bgGrayAvg = 0.0;
|
||
bgGrayAvg = bg_mean.at<double>(0, 0);
|
||
bgFix.release();
|
||
|
||
cv::Mat dst;
|
||
cv::boxFilter(wm, dst, -1, cv::Size(3, 3));
|
||
|
||
cv::MatIterator_<uchar> it = dst.begin<uchar>();
|
||
cv::MatIterator_<uchar> end = dst.end<uchar>();
|
||
double area = 0.0;
|
||
while (it != end)
|
||
{
|
||
double gray = *it;
|
||
if (gray > bgGrayAvg + rcc->m_GrayOffset || gray < bgGrayAvg - rcc->m_GrayOffset) {
|
||
*it = 255;
|
||
area += 1.0;
|
||
}
|
||
else {
|
||
*it = 0;
|
||
}
|
||
it++;
|
||
}
|
||
|
||
//cv::imwrite("g:/testimage/dst.bmp", dst);
|
||
//g_log->TraceInfo("bin");
|
||
vector<cv::Vec4i> check_hierarchy;
|
||
vector<vector<cv::Point>> check_contours;
|
||
findContours(dst, check_contours, check_hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_NONE);
|
||
|
||
EnterCriticalSection(&disp_cs);
|
||
drawContours(wm, check_contours, -1, cv::Scalar(255, 0, 0), 2);
|
||
//cv::imwrite("g:/testimage/wm.bmp", wm);
|
||
cv::resize(wm, m_WarpDst, m_WarpDst.size());
|
||
isDispUpdated = true;
|
||
LeaveCriticalSection(&disp_cs);
|
||
|
||
if (img)delete[] img;
|
||
|
||
//g_log->TraceInfo("countarea");
|
||
double realArea = area / rcc->m_ImageScale / rcc->m_ImageScale;
|
||
if (realArea > 2500)return false;
|
||
|
||
if (metadata && layer > 0) {
|
||
|
||
if (metadata == nullptr || layer > metadata->GetLayerCount())return true;
|
||
MetaData::Layer* player = metadata->GetCurrentLayer();
|
||
if (player == NULL || player->index != layer) {
|
||
if (metadata->LoadLayerByIndex(layer))
|
||
player = metadata->GetCurrentLayer();
|
||
else
|
||
return true;
|
||
}
|
||
|
||
|
||
float halfWidth = (float)(m_CameraCalibrationCfg->m_PlatformTopRightX->GetValue() - m_CameraCalibrationCfg->m_PlatformTopLeftX->GetValue()) * rcc->m_ImageScale / 2.0f;
|
||
float halfHigh = (float)(m_CameraCalibrationCfg->m_PlatformTopRightY->GetValue() - m_CameraCalibrationCfg->m_PlatformBottomRightY->GetValue()) * rcc->m_ImageScale / 2.0f;
|
||
map<int, RecoatCheckInfo*> infos;
|
||
|
||
metadata->LockMainDB();
|
||
for (std::map<int, MetaData::DataBlockList*>::iterator it = player->data_blocks_map.begin(); it != player->data_blocks_map.end(); it++) {
|
||
|
||
int partid = it->first;
|
||
MetaData::Part* part = metadata->GetPart(partid);
|
||
if (!part->print_enable)
|
||
continue;
|
||
MetaData::DataBlockList* datas = it->second;
|
||
if (datas == NULL)continue;
|
||
float dotWidth = 0.0f;
|
||
vector<BPBinary::BinDataBlock*> hatchingDB;
|
||
vector<BPBinary::BinDataBlock*> supportDB;
|
||
RecoatCheckInfo* info = new RecoatCheckInfo();
|
||
for (unsigned int i = 0; i < datas->size(); ++i) {
|
||
BPBinary::BinDataBlock* pdb = metadata->GetDataBlock((*datas)[i]);
|
||
if (!pdb)break;
|
||
MetaData::ParameterSet* ps = metadata->GetParameterSet((*datas)[i]->references->process);
|
||
if (!ps) {
|
||
continue;
|
||
}
|
||
|
||
if (ps->set_type.find("Hatching") != ps->set_type.npos)
|
||
{
|
||
if (pdb->type == BIN_VECTOR) {
|
||
hatchingDB.push_back(pdb);
|
||
}
|
||
}
|
||
else if (ps->set_type.find("Support") != ps->set_type.npos) {
|
||
supportDB.push_back(pdb);
|
||
}
|
||
}
|
||
int calcCount = 0;
|
||
vector<CalcVar> calcV;
|
||
float AreaSum = 0.0f;
|
||
for (size_t i = 0; i < hatchingDB.size(); i++) {
|
||
for (size_t j = 0; j < hatchingDB[i]->point_indexs.size(); ++j) {
|
||
BPBinary::VectorPoint* pvp = (BPBinary::VectorPoint*)hatchingDB[i]->point_indexs[j];
|
||
CalcVar cv;
|
||
cv.difx = pvp->x2 - pvp->x1;
|
||
cv.dify = pvp->y2 - pvp->y1;
|
||
cv.a = -(pvp->y2 - pvp->y1);
|
||
cv.b = pvp->x2 - pvp->x1;
|
||
cv.c = (pvp->y2 - pvp->y1) * pvp->x1 - (pvp->x2 - pvp->x1) * pvp->y1;
|
||
calcV.push_back(cv);
|
||
calcCount++;
|
||
if (calcCount >= 10)break;
|
||
}
|
||
if (calcCount >= 10)break;
|
||
}
|
||
if (calcV.size() < 10) {
|
||
dotWidth = 0.1f;
|
||
}
|
||
else {
|
||
CalcVar preV = calcV[0];
|
||
float disSum = 0.0f;
|
||
int count = 0;
|
||
float maxcalc = -FLT_MAX;
|
||
float mincalc = FLT_MAX;
|
||
for (size_t i = 1; i < calcV.size(); i++) {
|
||
CalcVar tempV = calcV[i];
|
||
float value = abs((preV.difx * tempV.dify) - (preV.dify * tempV.difx));
|
||
if (value < 0.01f) {
|
||
float calcT = preV.a * preV.a + preV.b * preV.b;
|
||
if (calcT > 0.0f) {
|
||
float calcSqr = sqrt(calcT);
|
||
if (calcSqr != 0.0f) {
|
||
float dis = abs(preV.c - preV.b * tempV.c / tempV.b) / calcSqr;
|
||
disSum += dis;
|
||
count++;
|
||
if (dis > maxcalc)maxcalc = dis;
|
||
if (dis < mincalc)mincalc = dis;
|
||
}
|
||
else {
|
||
preV = tempV;
|
||
continue;
|
||
}
|
||
}
|
||
else {
|
||
preV = tempV;
|
||
continue;
|
||
}
|
||
}
|
||
preV = tempV;
|
||
}
|
||
if (count >= 3) {
|
||
disSum -= maxcalc;
|
||
disSum -= mincalc;
|
||
dotWidth = disSum / (count - 2);
|
||
}
|
||
else {
|
||
dotWidth = 0.1f;
|
||
}
|
||
}
|
||
float xmin = FLT_MAX;
|
||
float xmax = -FLT_MAX;
|
||
float ymin = FLT_MAX;
|
||
float ymax = -FLT_MAX;
|
||
for (size_t i = 0; i < hatchingDB.size(); i++) {
|
||
for (size_t j = 0; j < hatchingDB[i]->point_indexs.size(); ++j) {
|
||
BPBinary::VectorPoint* pvp = (BPBinary::VectorPoint*)hatchingDB[i]->point_indexs[j];
|
||
float dsq = (pvp->x1 - pvp->x2) * (pvp->x1 - pvp->x2) + (pvp->y1 - pvp->y2) * (pvp->y1 - pvp->y2);
|
||
if (dsq > 0.0f) {
|
||
float dis = sqrt(dsq);
|
||
AreaSum = AreaSum + (dis * dotWidth);
|
||
}
|
||
if (xmin > pvp->x1)xmin = pvp->x1;
|
||
if (xmin > pvp->x2)xmin = pvp->x2;
|
||
if (xmax < pvp->x1)xmax = pvp->x1;
|
||
if (xmax < pvp->x2)xmax = pvp->x2;
|
||
if (ymin > pvp->y1)ymin = pvp->y1;
|
||
if (ymin > pvp->y2)ymin = pvp->y2;
|
||
if (ymax < pvp->y1)ymax = pvp->y1;
|
||
if (ymax < pvp->y2)ymax = pvp->y2;
|
||
}
|
||
}
|
||
for (size_t i = 0; i < supportDB.size(); i++) {
|
||
BPBinary::BinDataBlock* pdb = supportDB[i];
|
||
if (pdb->type == BIN_VECTOR) {
|
||
for (size_t j = 0; j < supportDB[i]->point_indexs.size(); ++j) {
|
||
BPBinary::VectorPoint* pvp = (BPBinary::VectorPoint*)supportDB[i]->point_indexs[j];
|
||
float dsq = (pvp->x1 - pvp->x2) * (pvp->x1 - pvp->x2) + (pvp->y1 - pvp->y2) * (pvp->y1 - pvp->y2);
|
||
if (dsq > 0.0f) {
|
||
float dis = sqrt(dsq);
|
||
AreaSum = AreaSum + (dis * dotWidth);
|
||
}
|
||
if (xmin > pvp->x1)xmin = pvp->x1;
|
||
if (xmin > pvp->x2)xmin = pvp->x2;
|
||
if (xmax < pvp->x1)xmax = pvp->x1;
|
||
if (xmax < pvp->x2)xmax = pvp->x2;
|
||
if (ymin > pvp->y1)ymin = pvp->y1;
|
||
if (ymin > pvp->y2)ymin = pvp->y2;
|
||
if (ymax < pvp->y1)ymax = pvp->y1;
|
||
if (ymax < pvp->y2)ymax = pvp->y2;
|
||
}
|
||
}
|
||
else if (pdb->type == BIN_CHAIN) {
|
||
for (unsigned int j = 0; j < pdb->point_indexs.size(); ++j) {
|
||
BPBinary::ChainPoint* point = (BPBinary::ChainPoint*)pdb->point_indexs[j];
|
||
if (point->points.empty())continue;
|
||
float prex = point->points[0]->x;
|
||
float prey = point->points[0]->y;
|
||
for (unsigned int k = 1; k < point->points.size(); ++k) {
|
||
float x = point->points[k]->x;
|
||
float y = point->points[k]->y;
|
||
float dsq = (prex - x) * (prex - x) + (prey - y) * (prey - y);
|
||
if (dsq > 0.0f) {
|
||
float dis = sqrt(dsq);
|
||
AreaSum = AreaSum + (dis * dotWidth);
|
||
}
|
||
prex = x;
|
||
prey = y;
|
||
if (xmin > x)xmin = x;
|
||
if (xmax < x)xmax = x;
|
||
if (ymin > y)ymin = y;
|
||
if (ymax < y)ymax = y;
|
||
}
|
||
}
|
||
}
|
||
hatchingDB.clear();
|
||
}
|
||
if (xmin == FLT_MAX)continue;
|
||
info->m_PartArea = AreaSum * rcc->m_ImageScale * rcc->m_ImageScale;
|
||
float xminfix = part->partPosBean.m_XOffset + xmin;
|
||
float xmaxfix = part->partPosBean.m_XOffset + xmax;
|
||
float yminfix = part->partPosBean.m_YOffset + ymin;
|
||
float ymaxfix = part->partPosBean.m_YOffset + ymax;
|
||
|
||
float point1x = (xminfix - part->partPosBean.m_PartCenterX) * cos(part->partPosBean.m_Radians) - (yminfix - part->partPosBean.m_PartCenterY) * sin(part->partPosBean.m_Radians) + part->partPosBean.m_PartCenterX;
|
||
float ppint1y = (xminfix - part->partPosBean.m_PartCenterX) * sin(part->partPosBean.m_Radians) + (yminfix - part->partPosBean.m_PartCenterY) * cos(part->partPosBean.m_Radians) + part->partPosBean.m_PartCenterY;
|
||
float point2x = (xminfix - part->partPosBean.m_PartCenterX) * cos(part->partPosBean.m_Radians) - (ymaxfix - part->partPosBean.m_PartCenterY) * sin(part->partPosBean.m_Radians) + part->partPosBean.m_PartCenterX;
|
||
float ppint2y = (xminfix - part->partPosBean.m_PartCenterX) * sin(part->partPosBean.m_Radians) + (ymaxfix - part->partPosBean.m_PartCenterY) * cos(part->partPosBean.m_Radians) + part->partPosBean.m_PartCenterY;
|
||
float point3x = (xmaxfix - part->partPosBean.m_PartCenterX) * cos(part->partPosBean.m_Radians) - (ymaxfix - part->partPosBean.m_PartCenterY) * sin(part->partPosBean.m_Radians) + part->partPosBean.m_PartCenterX;
|
||
float ppint3y = (xmaxfix - part->partPosBean.m_PartCenterX) * sin(part->partPosBean.m_Radians) + (ymaxfix - part->partPosBean.m_PartCenterY) * cos(part->partPosBean.m_Radians) + part->partPosBean.m_PartCenterY;
|
||
float point4x = (xmaxfix - part->partPosBean.m_PartCenterX) * cos(part->partPosBean.m_Radians) - (yminfix - part->partPosBean.m_PartCenterY) * sin(part->partPosBean.m_Radians) + part->partPosBean.m_PartCenterX;
|
||
float ppint4y = (xmaxfix - part->partPosBean.m_PartCenterX) * sin(part->partPosBean.m_Radians) + (yminfix - part->partPosBean.m_PartCenterY) * cos(part->partPosBean.m_Radians) + part->partPosBean.m_PartCenterY;
|
||
|
||
vector<cv::Point> points;
|
||
points.push_back(cv::Point(point1x * rcc->m_ImageScale + halfWidth, halfHigh - ppint1y * rcc->m_ImageScale));
|
||
points.push_back(cv::Point(point2x * rcc->m_ImageScale + halfWidth, halfHigh - ppint2y * rcc->m_ImageScale));
|
||
points.push_back(cv::Point(point3x * rcc->m_ImageScale + halfWidth, halfHigh - ppint3y * rcc->m_ImageScale));
|
||
points.push_back(cv::Point(point4x * rcc->m_ImageScale + halfWidth, halfHigh - ppint4y * rcc->m_ImageScale));
|
||
info->m_Counter.push_back(points);
|
||
infos[partid] = info;
|
||
}
|
||
metadata->UnLockMainDB();
|
||
|
||
double AreaSum = 0.0;
|
||
for (map<int, RecoatCheckInfo*>::iterator it = infos.begin(); it != infos.end(); it++) {
|
||
RecoatCheckInfo* info = it->second;
|
||
AreaSum += info->m_PartArea;
|
||
delete info;
|
||
}
|
||
infos.clear();
|
||
|
||
|
||
float areaRat = area / AreaSum * 100.0f;
|
||
if (areaRat > rcc->m_UncoverPercentage)
|
||
{
|
||
return false;
|
||
}
|
||
else return true;
|
||
|
||
}
|
||
else return true;
|
||
}
|
||
|
||
void RecoatCheck::TestCheck()
|
||
{
|
||
if (!m_Camera)return;
|
||
if (!m_Camera->IsConnect())return;
|
||
MachineCfg* mcfg = ConfigManager::GetInstance()->GetMachineCfg();
|
||
RecoatCheckCfg* rcc = ConfigManager::GetInstance()->GetRecoatCheckCfg();
|
||
if (!rcc->m_Enable)return;
|
||
if (m_CameraCalibrationCfg->m_CameraMatrix00->GetValue() == 0.0 || !Calibration::m_CoverImage) {
|
||
return;
|
||
}
|
||
|
||
int width = 0, height = 0, datasize = 0;
|
||
m_Camera->GetOriginSize(width, height, datasize);
|
||
if (datasize == 0)return;
|
||
unsigned char* img = new unsigned char[datasize];
|
||
if (!m_Camera->GetRawImage(img))
|
||
{
|
||
if (img)delete[] img;
|
||
return;
|
||
}
|
||
cv::Mat image(height, width, CV_8U, img);
|
||
switch (m_ExtCfg->m_ShowImageRotateAngle)
|
||
{
|
||
case ExtCfg::Angle_0: {
|
||
}break;
|
||
case ExtCfg::Angle_90: {
|
||
cv::rotate(image, image, cv::ROTATE_90_COUNTERCLOCKWISE);
|
||
}break;
|
||
case ExtCfg::Angle_180: {
|
||
cv::rotate(image, image, cv::ROTATE_180);
|
||
}break;
|
||
case ExtCfg::Angle_270: {
|
||
cv::rotate(image, image, cv::ROTATE_90_CLOCKWISE);
|
||
}break;
|
||
}
|
||
|
||
cv::Mat divImage;
|
||
cv::Scalar partMean = cv::mean(image);
|
||
cv::divide(image, Calibration::m_CoverImage->m_ImageMat, divImage, partMean.val[0]);
|
||
image.release();
|
||
|
||
//cv::imwrite("g:/testimage/div.bmp", divImage);
|
||
|
||
cv::Mat cameraMatrix = cv::Mat(3, 3, CV_64FC1, cv::Scalar::all(0)); //摄像机内参数矩阵
|
||
cv::Mat distCoeffs = cv::Mat(1, 5, CV_64FC1, cv::Scalar::all(0)); //摄像机的5个畸变系数:k1,k2,p1,p2,k3
|
||
|
||
cameraMatrix.at<double>(0, 0) = m_CameraCalibrationCfg->m_CameraMatrix00->GetValue();
|
||
cameraMatrix.at<double>(0, 1) = m_CameraCalibrationCfg->m_CameraMatrix01->GetValue();
|
||
cameraMatrix.at<double>(0, 2) = m_CameraCalibrationCfg->m_CameraMatrix02->GetValue();
|
||
cameraMatrix.at<double>(1, 0) = m_CameraCalibrationCfg->m_CameraMatrix10->GetValue();
|
||
cameraMatrix.at<double>(1, 1) = m_CameraCalibrationCfg->m_CameraMatrix11->GetValue();
|
||
cameraMatrix.at<double>(1, 2) = m_CameraCalibrationCfg->m_CameraMatrix12->GetValue();
|
||
cameraMatrix.at<double>(2, 0) = m_CameraCalibrationCfg->m_CameraMatrix20->GetValue();
|
||
cameraMatrix.at<double>(2, 1) = m_CameraCalibrationCfg->m_CameraMatrix21->GetValue();
|
||
cameraMatrix.at<double>(2, 2) = m_CameraCalibrationCfg->m_CameraMatrix22->GetValue();
|
||
distCoeffs.at<double>(0, 0) = m_CameraCalibrationCfg->m_DistCoeffs0->GetValue();
|
||
distCoeffs.at<double>(0, 1) = m_CameraCalibrationCfg->m_DistCoeffs1->GetValue();
|
||
distCoeffs.at<double>(0, 2) = m_CameraCalibrationCfg->m_DistCoeffs2->GetValue();
|
||
distCoeffs.at<double>(0, 3) = m_CameraCalibrationCfg->m_DistCoeffs3->GetValue();
|
||
distCoeffs.at<double>(0, 4) = m_CameraCalibrationCfg->m_DistCoeffs4->GetValue();
|
||
cv::Mat calImage;
|
||
undistort(divImage, calImage, cameraMatrix, distCoeffs);
|
||
//cv::imwrite("g:/testimage/cal.bmp", calImage);
|
||
cv::Point2f srcTri[4];
|
||
srcTri[0] = cv::Point2f((float)m_CameraCalibrationCfg->m_ImageTopLeftX->GetValue(), (float)m_CameraCalibrationCfg->m_ImageTopLeftY->GetValue());
|
||
srcTri[1] = cv::Point2f((float)m_CameraCalibrationCfg->m_ImageTopRightX->GetValue(), (float)m_CameraCalibrationCfg->m_ImageTopRightY->GetValue());
|
||
srcTri[2] = cv::Point2f((float)m_CameraCalibrationCfg->m_ImageBottomRightX->GetValue(), (float)m_CameraCalibrationCfg->m_ImageBottomRightY->GetValue());
|
||
srcTri[3] = cv::Point2f((float)m_CameraCalibrationCfg->m_ImageBottomLeftX->GetValue(), (float)m_CameraCalibrationCfg->m_ImageBottomLeftY->GetValue());
|
||
cv::Point2f tempTri[4];
|
||
|
||
int tx = (m_CameraCalibrationCfg->m_PlatformTopRightX->GetValue() - m_CameraCalibrationCfg->m_PlatformTopLeftX->GetValue()) * rcc->m_ImageScale;
|
||
int ty = (m_CameraCalibrationCfg->m_PlatformTopRightY->GetValue() - m_CameraCalibrationCfg->m_PlatformBottomRightY->GetValue()) * rcc->m_ImageScale;
|
||
|
||
tempTri[0] = cv::Point2f(0.0f, 0.0f);
|
||
tempTri[1] = cv::Point2f((float)tx, 0.0f);
|
||
tempTri[2] = cv::Point2f((float)tx, (float)ty);
|
||
tempTri[3] = cv::Point2f(0.0f, (float)ty);
|
||
cv::Mat warp_mat = cv::getPerspectiveTransform(srcTri, tempTri);
|
||
cv::Mat wm(cv::Size(tx, ty), CV_8U);
|
||
cv::Mat bgFix(cv::Size(tx, ty), CV_8U);
|
||
warpPerspective(calImage, wm, warp_mat, wm.size());
|
||
//cv::imwrite("g:/testimage/war.bmp", wm);
|
||
warpPerspective(Calibration::m_CoverImage->m_ImageMat, bgFix, warp_mat, bgFix.size());
|
||
cv::Mat bg_mean, bg_stddev;
|
||
cv::meanStdDev(bgFix, bg_mean, bg_stddev);
|
||
double bgGrayAvg = 0.0;
|
||
bgGrayAvg = bg_mean.at<double>(0, 0);
|
||
bgFix.release();
|
||
|
||
cv::Mat dst;
|
||
cv::boxFilter(wm, dst, -1, cv::Size(3, 3));
|
||
|
||
if (m_CameraCalibrationCfg->m_BlackFace->GetValue()) {
|
||
cv::threshold(dst, dst, bgGrayAvg - 20, 255, cv::ThresholdTypes::THRESH_BINARY_INV);
|
||
}
|
||
else {
|
||
cv::threshold(dst, dst, bgGrayAvg + 20, 255, cv::ThresholdTypes::THRESH_BINARY);
|
||
}
|
||
//cv::imwrite("g:/testimage/dst.bmp", dst);
|
||
vector<cv::Vec4i> check_hierarchy;
|
||
vector<vector<cv::Point>> check_contours;
|
||
|
||
findContours(dst, check_contours, check_hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_NONE);
|
||
double area = 0.0f;
|
||
for (size_t i = 0; i < check_contours.size(); i++) {
|
||
area += contourArea(check_contours[i]);
|
||
}
|
||
|
||
EnterCriticalSection(&disp_cs);
|
||
drawContours(wm, check_contours, -1, cv::Scalar(255, 0, 0), 2);
|
||
cv::resize(wm, m_WarpDst, m_WarpDst.size());
|
||
isDispUpdated = true;
|
||
LeaveCriticalSection(&disp_cs);
|
||
} |