赞
踩
(识别接口比ROI接口的函数参数少一个传入的ROI)
- //平直冷侧翅片
- bool ImageProcessingTest::straightColdSideFin_ROI(cv::Mat img, cv::Rect ROI, std::vector<cv::Point>& topList, std::vector<cv::Point>& bottomList, cv::Mat & canvas, bool debug)
- {
- int endRes = 0;
- bool result = false;
- img.copyTo(canvas);
- //top = cv::Point(0, 0);
- //bottom = cv::Point(0, 0);
-
- cv::Mat imgOriginal;
- bool ROI_flag;//是否有给信息区
- cv::Point ROI_tl = cv::Point2i(ROI.x, ROI.y);
- cv::Point ROI_br = cv::Point2i(ROI.x + ROI.width, ROI.y + ROI.height);
- if (ROI_tl == cv::Point(0, 0) && ROI_br == cv::Point(0, 0) || ROI.width == 0 || ROI.height == 0)
- {
- img.copyTo(imgOriginal);
- ROI_flag = false;
- }
- else
- {
- if (ROI_tl.x > ROI_br.x || ROI_tl.y > ROI_br.y)//信息区两点疑似传反
- {
- printf("信息区两点疑似传反!");
- return false;
- }
- if (ROI_tl.x < 0 || ROI_br.x > img.cols || ROI_tl.y < 0 || ROI_br.y > img.rows)//信息区的框选超出图像范围
- {
- printf("信息区的框选超出图像范围!");
- return false;
- }
- if (abs(ROI_tl.x - ROI_br.x) > img.cols || abs(ROI_tl.y - ROI_br.y) > img.rows)//信息区大小超出图像大小
- {
- printf("信息区大小超出图像大小!");
- return false;
- }
-
- //此时不合法的ROI都已提前返回false
-
- cv::Rect roi(ROI_tl.x, ROI_tl.y, ROI_br.x - ROI_tl.x, ROI_br.y - ROI_tl.y);
- imgOriginal = img(roi); //裁剪出的ROI区域放于imgOriginal
- ROI_flag = true;
- }
-
- result = straightColdSideFin(imgOriginal, topList, bottomList, canvas, debug);//调用识别算法
-
- if (debug) {
- for (int i = 0; i < topList.size(); i++) {
- cv::Point top = topList.at(i);
- top += ROI_tl;
- if (debug) printf("-------------------------------------****------ roiF top=【%d, %d】\n", top.x, top.y);
- }
- for (int i = 0; i < bottomList.size(); i++) {
- cv::Point bottom = bottomList.at(i);
- bottom += ROI_tl;
- if (debug) printf("-------------------------------------****------ roiF bottom=【%d, %d】\n", bottom.x, bottom.y);
- }
- }
- //if (debug) printf("-------------------------------------****------ roiF top=【%d, %d】, bottom=【%d, %d】\n", top.x, top.y, bottom.x, bottom.y);
- //img.copyTo(canvas);
-
-
- x值和y值补上ROI左上点x和y
- //if (ROI_flag) {
- // if (Corner != cv::Point(0, 0))
- // {
- // Corner.x += ROI_tl.x;
- // Corner.y += ROI_tl.y;
- // }
- //}
-
- img.copyTo(canvas);//调试时注释掉
- if (result)
- {
- cv::Point textP(6, 0);//演示用
- endRes = 1;
- for (int i = 0; i < topList.size(); i++) {
- topList.at(i) += ROI_tl;
- cv::Point top = topList.at(i);
- circle(canvas, top, 2, cv::Scalar(0, 69, 255), -1);
- cv::putText(canvas, to_string(i), top + textP, cv::FONT_HERSHEY_COMPLEX, 0.45, cv::Scalar(0, 69, 255), 1);//演示用
- }
- for (int i = 0; i < bottomList.size(); i++) {
- bottomList.at(i) += ROI_tl;
- cv::Point bottom = bottomList.at(i);
- circle(canvas, bottom, 2, cv::Scalar(255, 69, 0), -1);
- cv::putText(canvas, to_string(i), bottom + textP, cv::FONT_HERSHEY_COMPLEX, 0.45, cv::Scalar(255, 69, 0), 1);//演示用
- }
- printf("topList.size()=%d , bottomList.size()=%d \n", topList.size(), bottomList.size());
- cv::putText(canvas, "true", { cv::Point(50, 50) }, cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(255, 255, 255), 1);
- }
- else
- {
- cv::putText(canvas, "false", { cv::Point(50, 50) }, cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(255, 255, 255), 1);
- }
-
-
- cv::Mat ROIcanvas;
- img.copyTo(ROIcanvas);
- if (debug) {
- if (debug) printf("topList.size()=%d , bottomList.size()=%d \n", topList.size(), bottomList.size());
- for (int i = 0; i < topList.size(); i++) {
- cv::Point top = topList.at(i);
- circle(ROIcanvas, top, 3, cv::Scalar(0, 69, 255), 1);
- if (debug) printf("-------------------------------------****------ roiF top=【%d, %d】\n", top.x, top.y);
- }
- for (int i = 0; i < bottomList.size(); i++) {
- cv::Point bottom = bottomList.at(i);
- circle(ROIcanvas, bottom, 3, cv::Scalar(255, 69, 0), 1);
- if (debug) printf("-------------------------------------****------ roiF bottom=【%d, %d】\n", bottom.x, bottom.y);
- }
- }
- //if (debug) circle(ROIcanvas, top, 3, cv::Scalar(0, 69, 255), 1);
- //if (debug) circle(ROIcanvas, bottom, 3, cv::Scalar(0, 69, 255), 1);
- if (debug) rectangle(ROIcanvas, ROI_tl, ROI_br, cv::Scalar(0, 0, 255), 1);
- rectangle(canvas, ROI_tl, ROI_br, cv::Scalar(0, 0, 255), 1);
- //if (debug) printf("-------------------------------------****------ roiF top=【%d, %d】, bottom=【%d, %d】\n", top.x, top.y, bottom.x, bottom.y);
- if (debug) imshow("ROI", ROIcanvas);
- if (debug) imshow("ROI接口_canvas", canvas);
- //ROIcanvas.copyTo(canvas);
-
- return result;
- }
调用main:
- //平直冷侧翅片:straightColdSideFin_ROI
- int main333() {
- bool flag = false;
- std::string filePath = "../img/straightColdSideFin/0616img";
-
-
- string resPath = "/output";
- //string resPath = filePath + "./output";
-
-
- cv::Point tlP = cv::Point(200, 0);
- cv::Point brP = cv::Point(950, 1024);
- std::vector<cv::Point> topList;
- std::vector<cv::Point> bottomList;
- cv::Mat canvas;
- ImageProcessingTest m_ImageProcessing;
- ofstream ofs("log.txt", ios::out);
- if (ofs)
- {
- ofs.clear();
- ofs << "日志启动" << endl;
- }
-
- vector<string> path_name;
-
-
- bool lianxu = false; //循环测试
-
- if (lianxu)
- {
- string path = filePath + cv::format("\\Image_20230614160744823.png");
- //string path = filePath + cv::format("\\Image_20230609111800152.png");
- //string path = filePath + cv::format("\\Image_20230601143638388.png");
- //string path = filePath + cv::format("\\Image_20230601143505168.png");
- //string path = filePath + cv::format("\\Image_20230609113049539.png");
- cv::Mat src = cv::imread(path);
- src.copyTo(canvas);
- cv::namedWindow("main_OriginalIMG", cv::RECURS_FILTER);
- cvSetMouseCallback("main_OriginalIMG", on_mouse_singleClick, 0);
- cv::imshow("main_OriginalIMG", src);
-
- //cv::Rect ROI = cv::Rect(0, 0, src.cols, src.rows);
- cv::Rect ROI = cv::Rect(tlP.x, tlP.y, brP.x - tlP.x, brP.y - tlP.y);
-
-
- bool flag = m_ImageProcessing.straightColdSideFin_ROI(src, ROI, topList, bottomList, canvas, true);
-
- cout << "\nmain ==== flag " << flag << endl;
- if (flag) {
- for (int i = 0; i < topList.size(); i++) {
- cv::Point top = topList.at(i);
- cout << "top = " << top.x << " " << top.y << endl;
- circle(canvas, top, 6, cv::Scalar(0, 69, 255), 1);
- }
- for (int i = 0; i < bottomList.size(); i++) {
- cv::Point bottom = bottomList.at(i);
- cout << "bottom = " << bottom.x << " " << bottom.y << endl;
- circle(canvas, bottom, 6, cv::Scalar(255, 69, 0), 1);
- }
- printf("topList.size()=%d , bottomList.size()=%d \n", topList.size(), bottomList.size());
- }
- canvas.copyTo(src);
- //cout << "\nmain ==== i " << endl;
- //cv::putText(src, to_string(flag), cv::Point(src.cols / 2 - 20, src.rows / 2 - 65), cv::FONT_HERSHEY_COMPLEX, 1.75, cv::Scalar(255, 135, 160), 3);
- cv::namedWindow("main-结果图src", cv::RECURS_FILTER);
- cvSetMouseCallback("main-结果图src", on_mouse_singleClick, 0);
- cv::imshow("main-结果图src", src);
- }
- else
- {
- vector<string> path_name;
- getAllFiles(filePath, path_name);
- cout << "path_name.size()=" << path_name.size() << endl;
-
- int number = 1;
- for (auto i : path_name)
- {
- cv::Mat src = cv::imread(filePath + "\\" + i);
- cout << endl << "number【" << number << "】src path=" << i << " ;" << endl;
- src.copyTo(canvas);
- cv::imshow("main_OriginalIMG", src);
-
- //将结果图写入文件方便查看结果
- int len = filePath.length();
- //i = i.substr(i.find_last_of('\\') + 1, len);
- cout << "i=" << i << endl;
- int time_start = clock();
- int time_end = clock();
-
- //cv::Rect ROI = cv::Rect(0, 0, src.cols, src.rows);
- cv::Rect ROI = cv::Rect(tlP.x, tlP.y, brP.x - tlP.x, brP.y - tlP.y);
-
-
- bool flag = m_ImageProcessing.straightColdSideFin_ROI(src, ROI, topList, bottomList, canvas);
-
-
- time_end = clock();
- printf("\n耗时 %d ms \n", time_end - time_start);
- cout << "\nmain ==== flag " << flag << endl;
- if (flag) {
- for (int i = 0; i < topList.size(); i++) {
- cv::Point top = topList.at(i);
- cout << "top = " << top.x << " " << top.y << endl;
- }
- for (int i = 0; i < bottomList.size(); i++) {
- cv::Point bottom = bottomList.at(i);
- cout << "bottom = " << bottom.x << " " << bottom.y << endl;
- }
- printf("topList.size()=%d , bottomList.size()=%d \n", topList.size(), bottomList.size());
- }
- canvas.copyTo(src);
- //cv::putText(src, to_string(flag), cv::Point(src.cols / 2 - 20, src.rows / 2 - 65), cv::FONT_HERSHEY_COMPLEX, 1.75, cv::Scalar(255, 135, 160), 3);
- cv::imshow("main-结果图src", src);
- cv::waitKey(10);
-
-
- //将结果图写入文件方便查看结果
- char* filePath_ = new char[len + 1];
- strcpy(filePath_, filePath.c_str());
-
- len = filePath.length();
- char* resPath_ = new char[len + 1];
- strcpy(resPath_, resPath.c_str());
- //i.erase(0, strlen(filePath_) - strlen(resPath_) - 2);
-
- string out = filePath + resPath;
- cout << "\nmain ==== i " << i << endl;
- out.append("\\").append(i);
-
- cout << "number【" << number << "】res path=" << out << endl;
- cv::imwrite(out, src);
- number++;
-
- cout << "path_name.size() = " << path_name.size() << endl;
- cout << "*********************************************************************************************************************" << endl;
- if (number == path_name.size()) break;
- }
- }
- cout << "main 循环结束!!!" << endl;
-
- ofs.close();
- cv::waitKey(0);
- system("Pause");
- return 0;
- }
- bool ImageProcess::arcPlusLine_ROI(cv::Mat img, cv::Rect ROI, cv::Point & top, cv::Mat & canvas, bool debug)
- {
- int endRes = 0;
- bool result = false;
- img.copyTo(canvas);
- top = cv::Point(0, 0);
-
- cv::Mat imgOriginal;
- bool ROI_flag;//是否有给信息区
- cv::Point ROI_tl = cv::Point2i(ROI.x, ROI.y);
- cv::Point ROI_br = cv::Point2i(ROI.x + ROI.width, ROI.y + ROI.height);
- if (ROI_tl == cv::Point(0, 0) && ROI_br == cv::Point(0, 0) || ROI.width == 0 || ROI.height == 0)
- {
- img.copyTo(imgOriginal);
- ROI_flag = false;
- }
- else
- {
- if (ROI_tl.x > ROI_br.x || ROI_tl.y > ROI_br.y)//信息区两点疑似传反
- {
- printf("信息区两点疑似传反!");
- return false;
- }
- if (ROI_tl.x < 0 || ROI_br.x > img.cols || ROI_tl.y < 0 || ROI_br.y > img.rows)//信息区的框选超出图像范围
- {
- printf("信息区的框选超出图像范围!");
- return false;
- }
- if (abs(ROI_tl.x - ROI_br.x) > img.cols || abs(ROI_tl.y - ROI_br.y) > img.rows)//信息区大小超出图像大小
- {
- printf("信息区大小超出图像大小!");
- return false;
- }
-
- //此时不合法的ROI都已提前返回false
-
- cv::Rect roi(ROI_tl.x, ROI_tl.y, ROI_br.x - ROI_tl.x, ROI_br.y - ROI_tl.y);
- imgOriginal = img(roi); //裁剪出的ROI区域放于imgOriginal
- ROI_flag = true;
- }
-
- result = arcPlusLine(imgOriginal, top, canvas, debug);//调用识别算法
-
- if (debug) printf("-------------------------------------****------ roiF top=【%d, %d】\n", top.x, top.y);
- //img.copyTo(canvas);
-
-
- //img.copyTo(canvas);//调试时注释掉
-
- cv::Mat t1;
- //canvas.convertTo(t1, -1, 900 / 100.0, 200 - 100);//第一次线性变换100
- canvas.convertTo(t1, -1, 900 / 100.0, 200 - 100);//第一次线性变换100
- if (debug)cv::imshow("线性变换ROI", t1);
- t1.copyTo(canvas);
-
- if (result)
- {
- endRes = 1;
- top += ROI_tl;
- cv::putText(canvas, "true", { cv::Point(50, 50) }, cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(255, 255, 255), 1);
- int w = 38;
- int thickness = 4;
- cv::Point curPoint = top;
- cv::line(canvas, curPoint, cv::Point(curPoint.x - w, curPoint.y), cv::Scalar(235, 135, 40), thickness);
- circle(canvas, top, 2, cv::Scalar(0, 69, 255), -1);
- circle(canvas, top, 63, cv::Scalar(0, 169, 255), 1);
- }
- else
- {
- cv::putText(canvas, "false", { cv::Point(50, 50) }, cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(255, 255, 255), 1);
- }
-
-
- cv::Mat ROIcanvas;
- img.copyTo(ROIcanvas);
- if (debug) circle(ROIcanvas, top, 3, cv::Scalar(0, 69, 255), 1);
- if (debug) circle(ROIcanvas, top, 63, cv::Scalar(0, 169, 255), 1);
- if (debug) rectangle(ROIcanvas, ROI_tl, ROI_br, cv::Scalar(0, 0, 255), 1);
- rectangle(canvas, ROI_tl, ROI_br, cv::Scalar(0, 0, 255), 1);
- if (debug) printf("-------------------------------------****------ roiF top=【%d, %d】 \n", top.x, top.y);
- if (debug) imshow("ROI", ROIcanvas);
- if (debug) imshow("ROI_canvas", canvas);
- //ROIcanvas.copyTo(canvas);
-
-
- //cv::Rect roi_(ROI_tl.x, ROI_tl.y, ROI_br.x - ROI_tl.x, ROI_br.y - ROI_tl.y);
- //if(!ROI_flag) canvas.copyTo(canvas);
- //else canvas = canvas(roi_); //裁剪出的ROI区域
-
- return result;
- }
调用main:
- //圆弧+直线 内角:arcPlusLine_ROI
- int main/*arcl*/() {
- bool flag = false;
- //std::string filePath = "E://vsproject//WeldingLine//1219img//in//宁波金波";
- //std::string filePath = "E://vsproject//WeldingLine//1219img//in//宁波金波//down";
- std::string filePath = "E://vsproject//WeldingLine//1219img//in//宁波金波//LogImg";
- //std::string filePath = "../img/ThreadedRoundPipe/0530img";
-
-
- string resPath = "/output";
- //string resPath = filePath + "./output";
-
-
- cv::Point tlP = cv::Point(200, 340);
- cv::Point brP = cv::Point(950, 999);
- cv::Point top(90, 90);
- cv::Mat canvas;
- VisualInterface m_ImageProcessing;
- //ImageProcess m_ImageProcessing;
- ofstream ofs("log.txt", ios::out);
- if (ofs)
- {
- ofs.clear();
- ofs << "日志启动" << endl;
- }
-
- vector<string> path_name;
- bool lineOnTop = true;
-
-
- bool getROI = !true;
- bool lianxu = false; //循环测试
-
- if (!lianxu)
- {
- string name = cv::format("\\Img_2024_03_12_15_01_57_350_TYPE_12_ROI_486_64_257_474_src.png");
- string path = filePath + name;
- //string path = filePath + cv::format("\\Image_20240228115544906.bmp");
- cv::Mat src = cv::imread(path);
- src.copyTo(canvas);
- cv::namedWindow("main_OriginalIMG", cv::RECURS_FILTER);
- cvSetMouseCallback("main_OriginalIMG", on_mouse_singleClick, 0);
- cv::imshow("main_OriginalIMG", src);
-
- cv::Rect ROI = cv::Rect(0, 0, src.cols, src.rows);
- //cv::Rect ROI = cv::Rect(tlP.x, tlP.y, brP.x - tlP.x, brP.y - tlP.y);
- if (getROI) ROI = getROIFromString(name);
-
-
- bool flag = m_ImageProcessing.arcPlusLine_ROI(src, ROI, top, canvas, lineOnTop, true);
-
- cout << "\nmain ==== flag " << flag << endl;
- if (flag) {
- cout << "top = " << top.x << " " << top.y << endl;
- }
- canvas.copyTo(src);
- //cout << "\nmain ==== i " << endl;
- circle(canvas, top, 63, cv::Scalar(0, 69, 255), 1);
- cv::putText(src, to_string(flag), cv::Point(src.cols / 2 - 20, src.rows / 2 - 165), cv::FONT_HERSHEY_COMPLEX, 1.75, cv::Scalar(255, 135, 160), 3);
- cv::namedWindow("main-结果图src", cv::RECURS_FILTER);
- cvSetMouseCallback("main-结果图src", on_mouse_singleClick, 0);
- cv::imshow("main-结果图src", src);
- }
- else
- {
- vector<string> path_name;
- getAllFiles(filePath, path_name);
- cout << "path_name.size()=" << path_name.size() << endl;
-
- int number = 1;
- for (auto i : path_name)
- {
- if (i.find("_res") != std::string::npos ) continue;
- if (i.find("png") == std::string::npos && i.find("bmp") == std::string::npos && i.find("jpg") == std::string::npos) continue;
- cv::Mat src = cv::imread(filePath + "\\" + i);
- cout << endl << "number【" << number << "】src path=" << i << " ;" << endl;
- src.copyTo(canvas);
- cv::imshow("main_OriginalIMG", src);
-
- //将结果图写入文件方便查看结果
- int len = filePath.length();
- //i = i.substr(i.find_last_of('\\') + 1, len);
- cout << "i=" << i << endl;
- int time_start = clock();
- int time_end = clock();
-
- cv::Rect ROI = cv::Rect(0, 0, src.cols, src.rows);
- //cv::Rect ROI = cv::Rect(tlP.x, tlP.y, brP.x - tlP.x, brP.y - tlP.y);
- if (getROI) ROI = getROIFromString(i);
-
-
- bool flag = m_ImageProcessing.arcPlusLine_ROI(src, ROI, top, canvas, lineOnTop, false);
-
-
- time_end = clock();
- printf("\n耗时 %d ms \n", time_end - time_start);
- cout << "\nmain ==== flag " << flag << endl;
- if (flag) {
- cout << "top = " << top.x << " " << top.y << endl;
- }
- canvas.copyTo(src);
- cv::putText(src, to_string(flag), cv::Point(src.cols / 2 - 20, src.rows / 2 - 65), cv::FONT_HERSHEY_COMPLEX, 1.75, cv::Scalar(255, 135, 160), 3);
- cv::imshow("main-结果图src", src);
- cv::waitKey(10);
-
-
- //将结果图写入文件方便查看结果
- char* filePath_ = new char[len + 1];
- strcpy(filePath_, filePath.c_str());
-
- len = filePath.length();
- char* resPath_ = new char[len + 1];
- strcpy(resPath_, resPath.c_str());
- //i.erase(0, strlen(filePath_) - strlen(resPath_) - 2);
-
- string out = filePath + resPath;
- cout << "\nmain ==== i " << i << endl;
- out.append("\\").append(i);
-
- cout << "number【" << number << "】res path=" << out << endl;
- cv::imwrite(out, src);
- number++;
-
- cout << "path_name.size() = " << path_name.size() << endl;
- cout << "*********************************************************************************************************************" << endl;
- if (number == path_name.size()) break;
- }
- }
- cout << "main 循环结束!!!" << endl;
-
- ofs.close();
- cv::waitKey(0);
- system("Pause");
- return 0;
- }
- cv::Rect getROIFromString(std::string str) {
- //图像名字格式:“SrcImg_2023_10_11_11_39_19_002_ROI_600_396_137_218_src.png”
- if (str.empty()) return cv::Rect(0, 0, 0, 0);
- using namespace std;
-
- const char *split = "_";
- char *p = strtok((char*)str.c_str(), split);
- std::vector<char*>data;
- while (p != NULL) {
- cout << p << endl;
- data.push_back(p);
- p = strtok(NULL, split);
- }
- //9 12;
-
- if (data.size() < 12)return cv::Rect();
-
- return cv::Rect(
- atoi(data[data.size() - 5]),
- atoi(data[data.size() - 4]),
- atoi(data[data.size() - 3]),
- atoi(data[data.size() - 2]));
-
- //return cv::Rect(
- // atoi(data[9]),
- // atoi(data[10]),
- // atoi(data[11]),
- // atoi(data[12]));
- }
- int ImageProcess::getPnt_2Dwith3D_MaiSi(cv::Mat imgHE, cv::Mat imgLE, cv::Mat & canvas, cv::Point & resPoint, bool &MaiSi_isTopPnt, cv::Rect ROI, bool debug)
- {
- int endRes = 0;
- bool result = false;
- imgHE.copyTo(canvas);
- cv::addWeighted(imgHE, 0.5, imgLE, 0.5, 0, canvas);
- ImageProcess pd;
-
- cv::Mat imgHE_roi;
- cv::Mat imgOriginal;
- bool ROI_flag;//是否有给信息区
- cv::Point ROI_tl = cv::Point2i(ROI.x, ROI.y);
- cv::Point ROI_br = cv::Point2i(ROI.x + ROI.width, ROI.y + ROI.height);
- cv::Mat img;
- imgLE.copyTo(img);
- if (ROI_tl == cv::Point(0, 0) && ROI_br == cv::Point(0, 0))
- {
- img.copyTo(imgOriginal);
- imgHE.copyTo(imgHE_roi);
- ROI_flag = false;
- }
- else
- {
- if (ROI_tl.x > ROI_br.x || ROI_tl.y > ROI_br.y)//信息区两点疑似传反
- {
- printf("信息区两点疑似传反!");
- return false;
- }
- if (ROI_tl.x < 0 || ROI_br.x > img.cols || ROI_tl.y < 0 || ROI_br.y > img.rows)//信息区的框选超出图像范围
- {
- printf("信息区的框选超出图像范围!");
- return false;
- }
- if (abs(ROI_tl.x - ROI_br.x) > img.cols || abs(ROI_tl.y - ROI_br.y) > img.rows)//信息区大小超出图像大小
- {
- printf("信息区大小超出图像大小!");
- return false;
- }
-
- //此时不合法的ROI都已提前返回false
-
- cv::Rect roi(ROI_tl.x, ROI_tl.y, ROI_br.x - ROI_tl.x, ROI_br.y - ROI_tl.y);
- imgOriginal = img(roi); //裁剪出的ROI区域放于imgOriginal
- imgHE_roi = imgHE(roi);
- ROI_flag = true;
- if (debug) {
- cv::Mat tmp;
- img.copyTo(tmp);
- rectangle(tmp, ROI_tl, ROI_br, cv::Scalar(0, 0, 255), 1);
- if (debug) cv::imshow("根据roi裁剪后进入识别的图", tmp);
- }
- }
-
-
- result = getPnt_2Dwith3D_MaiSi(imgHE_roi, imgOriginal, canvas, resPoint, MaiSi_isTopPnt, debug);
-
-
-
- cv::addWeighted(imgHE, 0.5, imgLE, 0.5, 0, canvas);
- //x值和y值补上ROI左上点x和y
- if (ROI_flag)
- {
- if (resPoint != cv::Point(0, 0))
- {
- resPoint.x += ROI_tl.x;
- resPoint.y += ROI_tl.y;
- }
- }
- if (debug) std::cout << img.size() << imgOriginal.size() << std::endl;
-
- if (result)
- {
- endRes = 1;
- cv::circle(canvas, resPoint, 3, cv::Scalar(0, 0, 255), -1, 8, 0);
- putText(canvas, "true", { cv::Point(250, 250) }, cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(255, 255, 255), 1);
- //putText(canvas, "EmbWare_Leg", { cv::Point(250, 350) }, cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(255, 255, 255), 1);
- if (MaiSi_isTopPnt) {
- putText(canvas, "isTopPnt", { resPoint + cv::Point(15, 5) }, cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(195, 165, 255), 1);
- }
- else {
- putText(canvas, "isBotPnt", { resPoint + cv::Point(15, 5) }, cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(155, 155, 255), 1);
- }
- Mark(canvas);
- }
- else
- {
- putText(canvas, "false", { cv::Point(250, 250) }, cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(255, 255, 255), 1);
- Mark(canvas);
- }
- rectangle(canvas, ROI_tl, ROI_br, cv::Scalar(0, 0, 255), 1);
-
- return endRes;
- }
- /*
- //圆弧+直线 求内角
- cv::Mat img, 原图
- cv::Rect ROI,
- cv::Point& Corner, 输出角点
- cv::Mat &canvas,效果图可视化
- bool lineOnTop = true,直线部分是否为较上端的角边,true则为是,false反之
- */
- bool arcPlusLine(cv::Mat imgOriginal, cv::Point& Corner, cv::Mat &canvas, bool debug = false);
- bool arcPlusLine_ROI(cv::Mat img, cv::Rect ROI, cv::Point& Corner, cv::Mat &canvas, bool lineOnTop = true, bool debug = false);
- bool ImageProcess::arcPlusLine_ROI(cv::Mat img, cv::Rect ROI, cv::Point & top, cv::Mat & canvas, bool lineOnTop, bool debug)
- {
- int endRes = 0;
- bool result = false;
- img.copyTo(canvas);
- top = cv::Point(0, 0);
-
- cv::Mat imgOriginal;
- bool ROI_flag;//是否有给信息区
- cv::Point ROI_tl = cv::Point2i(ROI.x, ROI.y);
- cv::Point ROI_br = cv::Point2i(ROI.x + ROI.width, ROI.y + ROI.height);
- if (ROI_tl == cv::Point(0, 0) && ROI_br == cv::Point(0, 0) || ROI.width == 0 || ROI.height == 0)
- {
- img.copyTo(imgOriginal);
- ROI_flag = false;
- }
- else
- {
- if (ROI_tl.x > ROI_br.x || ROI_tl.y > ROI_br.y)//信息区两点疑似传反
- {
- printf("信息区两点疑似传反!");
- return false;
- }
- if (ROI_tl.x < 0 || ROI_br.x > img.cols || ROI_tl.y < 0 || ROI_br.y > img.rows)//信息区的框选超出图像范围
- {
- printf("信息区的框选超出图像范围!");
- return false;
- }
- if (abs(ROI_tl.x - ROI_br.x) > img.cols || abs(ROI_tl.y - ROI_br.y) > img.rows)//信息区大小超出图像大小
- {
- printf("信息区大小超出图像大小!");
- return false;
- }
-
- //此时不合法的ROI都已提前返回false
-
- cv::Rect roi(ROI_tl.x, ROI_tl.y, ROI_br.x - ROI_tl.x, ROI_br.y - ROI_tl.y);
- imgOriginal = img(roi); //裁剪出的ROI区域放于imgOriginal
- ROI_flag = true;
- }
-
- if (lineOnTop) {
- result = arcPlusLine(imgOriginal, top, canvas, debug);//调用识别算法
- }
- else {
- cv::Mat fpMt;
- cv::flip(imgOriginal, fpMt, 0); // 上下翻转 x对称
- result = arcPlusLine(fpMt, top, canvas, debug);//调用识别算法
- if (result) {
- top.y = fpMt.rows - top.y - 1;
- }
- }
- cv::Mat lockCanvas = canvas.clone();
-
-
- if (debug) printf("-------------------------------------****------ roiF top=【%d, %d】\n", top.x, top.y);
- //img.copyTo(canvas);
-
-
- //img.copyTo(canvas);//调试时注释掉
-
- //cv::Mat t1;
- //canvas.convertTo(t1, -1, 900 / 100.0, 200 - 100);//第一次线性变换100
- //if (debug)cv::imshow("线性变换ROI", t1);
- //t1.copyTo(canvas);
-
- if (result)
- {
- endRes = 1;
- top += ROI_tl;
- cv::putText(canvas, "true", { cv::Point(50, 50) }, cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(255, 255, 255), 1);
- int w = 38;
- int thickness = 4;
- cv::Point curPoint = top;
- cv::line(canvas, curPoint, cv::Point(curPoint.x - w, curPoint.y), cv::Scalar(235, 135, 40), thickness);
- circle(canvas, top, 2, cv::Scalar(0, 69, 255), -1);
- circle(canvas, top, 63, cv::Scalar(0, 169, 255), 1);
- }
- else
- {
- cv::putText(canvas, "false", { cv::Point(50, 50) }, cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(255, 255, 255), 1);
- }
-
-
- cv::Mat ROIcanvas;
- img.copyTo(ROIcanvas);
- if (debug) circle(ROIcanvas, top, 3, cv::Scalar(0, 69, 255), 1);
- if (debug) circle(ROIcanvas, top, 63, cv::Scalar(0, 169, 255), 1);
- if (debug) rectangle(ROIcanvas, ROI_tl, ROI_br, cv::Scalar(0, 0, 255), 1);
- rectangle(canvas, ROI_tl, ROI_br, cv::Scalar(0, 0, 255), 1);
- if (debug) printf("-------------------------------------****------ roiF top=【%d, %d】 \n", top.x, top.y);
- if (debug) imshow("ROI", ROIcanvas);
- if (debug) imshow("ROI_canvas", canvas);
- //ROIcanvas.copyTo(canvas);
-
-
- //cv::Rect roi_(ROI_tl.x, ROI_tl.y, ROI_br.x - ROI_tl.x, ROI_br.y - ROI_tl.y);
- //if(!ROI_flag) canvas.copyTo(canvas);
- //else canvas = canvas(roi_); //裁剪出的ROI区域
-
- lockCanvas.copyTo(canvas);
- return result;
- }
调用main:
- // 内角:arcPlusLine_ROI
- int main/*arcl*/() {
- bool flag = false;
- std::string filePath = "E://vsproject//WeldingLine//1219img//in//宁波金波";
- //std::string filePath = "E://vsproject//WeldingLine//1219img//in//宁波金波//down";
- //std::string filePath = "../img/ThreadedRoundPipe/0530img";
-
-
- string resPath = "/output";
- //string resPath = filePath + "./output";
-
-
- cv::Point tlP = cv::Point(200, 340);
- cv::Point brP = cv::Point(950, 999);
- cv::Point top(90, 90);
- cv::Mat canvas;
- //VisualInterface m_ImageProcessing;
- ImageProcess m_ImageProcessing;
- ofstream ofs("log.txt", ios::out);
- if (ofs)
- {
- ofs.clear();
- ofs << "日志启动" << endl;
- }
-
- vector<string> path_name;
- bool lineOnTop = true;
-
-
- bool lianxu = false; //循环测试
-
- if (lianxu)
- {
- string path = filePath + cv::format("\\Image_20240304155500627.png");
- //string path = filePath + cv::format("\\Image_20240228115544906.bmp");
- cv::Mat src = cv::imread(path);
- src.copyTo(canvas);
- cv::namedWindow("main_OriginalIMG", cv::RECURS_FILTER);
- cvSetMouseCallback("main_OriginalIMG", on_mouse_singleClick, 0);
- cv::imshow("main_OriginalIMG", src);
-
- cv::Rect ROI = cv::Rect(0, 0, src.cols, src.rows);
- //cv::Rect ROI = cv::Rect(tlP.x, tlP.y, brP.x - tlP.x, brP.y - tlP.y);
-
-
- bool flag = m_ImageProcessing.arcPlusLine_ROI(src, ROI, top, canvas, lineOnTop, true);
-
- cout << "\nmain ==== flag " << flag << endl;
- if (flag) {
- cout << "top = " << top.x << " " << top.y << endl;
- }
- canvas.copyTo(src);
- //cout << "\nmain ==== i " << endl;
- circle(canvas, top, 63, cv::Scalar(0, 69, 255), 1);
- cv::putText(src, to_string(flag), cv::Point(src.cols / 2 - 20, src.rows / 2 - 165), cv::FONT_HERSHEY_COMPLEX, 1.75, cv::Scalar(255, 135, 160), 3);
- cv::namedWindow("main-结果图src", cv::RECURS_FILTER);
- cvSetMouseCallback("main-结果图src", on_mouse_singleClick, 0);
- cv::imshow("main-结果图src", src);
- }
- else
- {
- vector<string> path_name;
- getAllFiles(filePath, path_name);
- cout << "path_name.size()=" << path_name.size() << endl;
-
- int number = 1;
- for (auto i : path_name)
- {
- if (i.find("png") == std::string::npos && i.find("bmp") == std::string::npos && i.find("jpg") == std::string::npos) continue;
- cv::Mat src = cv::imread(filePath + "\\" + i);
- cout << endl << "number【" << number << "】src path=" << i << " ;" << endl;
- src.copyTo(canvas);
- cv::imshow("main_OriginalIMG", src);
-
- //将结果图写入文件方便查看结果
- int len = filePath.length();
- //i = i.substr(i.find_last_of('\\') + 1, len);
- cout << "i=" << i << endl;
- int time_start = clock();
- int time_end = clock();
-
- cv::Rect ROI = cv::Rect(0, 0, src.cols, src.rows);
- //cv::Rect ROI = cv::Rect(tlP.x, tlP.y, brP.x - tlP.x, brP.y - tlP.y);
-
-
- bool flag = m_ImageProcessing.arcPlusLine_ROI(src, ROI, top, canvas, lineOnTop, false);
-
-
- time_end = clock();
- printf("\n耗时 %d ms \n", time_end - time_start);
- cout << "\nmain ==== flag " << flag << endl;
- if (flag) {
- cout << "top = " << top.x << " " << top.y << endl;
- }
- canvas.copyTo(src);
- cv::putText(src, to_string(flag), cv::Point(src.cols / 2 - 20, src.rows / 2 - 65), cv::FONT_HERSHEY_COMPLEX, 1.75, cv::Scalar(255, 135, 160), 3);
- cv::imshow("main-结果图src", src);
- cv::waitKey(10);
-
-
- //将结果图写入文件方便查看结果
- char* filePath_ = new char[len + 1];
- strcpy(filePath_, filePath.c_str());
-
- len = filePath.length();
- char* resPath_ = new char[len + 1];
- strcpy(resPath_, resPath.c_str());
- //i.erase(0, strlen(filePath_) - strlen(resPath_) - 2);
-
- string out = filePath + resPath;
- cout << "\nmain ==== i " << i << endl;
- out.append("\\").append(i);
-
- cout << "number【" << number << "】res path=" << out << endl;
- cv::imwrite(out, src);
- number++;
-
- cout << "path_name.size() = " << path_name.size() << endl;
- cout << "*********************************************************************************************************************" << endl;
- if (number == path_name.size()) break;
- }
- }
- cout << "main 循环结束!!!" << endl;
-
- ofs.close();
- cv::waitKey(0);
- system("Pause");
- return 0;
- }
- bool PTank_imgProcess::arcPlusLine_ROI(cv::Mat img, cv::Rect ROI, cv::Point & top, std::vector<cv::Point>& allPntList, cv::Mat & canvas, bool lineOnTop, bool debug)
- {
- int endRes = 0;
- bool result = false;
- img.copyTo(canvas);
- top = cv::Point(0, 0);
-
- cv::Mat imgOriginal;
- bool ROI_flag;//是否有给信息区
- cv::Point ROI_tl = cv::Point2i(ROI.x, ROI.y);
- cv::Point ROI_br = cv::Point2i(ROI.x + ROI.width, ROI.y + ROI.height);
- if (ROI_tl == cv::Point(0, 0) && ROI_br == cv::Point(0, 0) || ROI.width == 0 || ROI.height == 0)
- {
- img.copyTo(imgOriginal);
- ROI_flag = false;
- }
- else
- {
- if (ROI_tl.x > ROI_br.x || ROI_tl.y > ROI_br.y)//信息区两点疑似传反
- {
- printf("信息区两点疑似传反!");
- return false;
- }
- if (ROI_tl.x < 0 || ROI_br.x > img.cols || ROI_tl.y < 0 || ROI_br.y > img.rows)//信息区的框选超出图像范围
- {
- printf("信息区的框选超出图像范围!");
- return false;
- }
- if (abs(ROI_tl.x - ROI_br.x) > img.cols || abs(ROI_tl.y - ROI_br.y) > img.rows)//信息区大小超出图像大小
- {
- printf("信息区大小超出图像大小!");
- return false;
- }
-
- //此时不合法的ROI都已提前返回false
-
- cv::Rect roi(ROI_tl.x, ROI_tl.y, ROI_br.x - ROI_tl.x, ROI_br.y - ROI_tl.y);
- imgOriginal = img(roi); //裁剪出的ROI区域放于imgOriginal
- ROI_flag = true;
- }
-
- cv::Mat lockCanvas;
- if (lineOnTop) {
- result = arcPlusLine(imgOriginal, top, allPntList, canvas, debug);//调用识别算法
- canvas.copyTo(lockCanvas);
- //for (int i = 0; i < allPntList.size(); i++) {
- // cv::line(lockCanvas, allPntList.at(i), cv::Point(allPntList.at(i).x - 3, allPntList.at(i).y), cv::Scalar(55, 195, 40), 1);
- //}
- }
- else {
- cv::Mat fpMt;
- cv::flip(imgOriginal, fpMt, 0); // 上下翻转 x对称
- result = arcPlusLine(fpMt, top, allPntList, canvas, debug);//调用识别算法
- canvas.copyTo(lockCanvas);
- if (result) {
- top.y = fpMt.rows - top.y - 1;
- for (int i = 0; i < allPntList.size(); i++) {
- //cv::line(lockCanvas, allPntList.at(i), cv::Point(allPntList.at(i).x - 3, allPntList.at(i).y), cv::Scalar(55, 195, 40), 1);
- allPntList.at(i).y = fpMt.rows - allPntList.at(i).y - 1;
- }
- }
- }
-
-
- if (debug) printf("-------------------------------------****------ roiF top=【%d, %d】\n", top.x, top.y);
- //img.copyTo(canvas);
-
-
- //img.copyTo(canvas);//调试时注释掉
-
- //cv::Mat t1;
- //canvas.convertTo(t1, -1, 900 / 100.0, 200 - 100);//第一次线性变换100
- //if (debug)cv::imshow("线性变换ROI", t1);
- //t1.copyTo(canvas);
-
- if (result)
- {
- img.copyTo(canvas);
- endRes = 1;
- top += ROI_tl;
- for (int i = 0; i < allPntList.size(); i++) {
- allPntList.at(i) += ROI_tl;
- }
- cv::putText(canvas, "true", { cv::Point(50, 50) }, cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(255, 255, 255), 1);
- int w = 38;
- int thickness = 4;
- cv::Point curPoint = top;
- cv::line(canvas, curPoint, cv::Point(curPoint.x - w, curPoint.y), cv::Scalar(235, 135, 40), thickness);
- circle(canvas, top, 2, cv::Scalar(0, 69, 255), -1);
- circle(canvas, top, 63, cv::Scalar(0, 169, 255), 1);
- w = 3;
- for (int i = 0; i < allPntList.size(); i++) {
- cv::Point curPoint = allPntList.at(i);
- cv::line(canvas, curPoint, cv::Point(curPoint.x - w, curPoint.y), cv::Scalar(55, 195, 40), 1);
- }
- }
- else
- {
- cv::putText(canvas, "false", { cv::Point(50, 50) }, cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(255, 255, 255), 1);
- }
-
-
- cv::Mat ROIcanvas;
- img.copyTo(ROIcanvas);
- if (debug) circle(ROIcanvas, top, 3, cv::Scalar(0, 69, 255), 1);
- if (debug) circle(ROIcanvas, top, 63, cv::Scalar(0, 169, 255), 1);
- if (debug) rectangle(ROIcanvas, ROI_tl, ROI_br, cv::Scalar(0, 0, 255), 1);
- rectangle(canvas, ROI_tl, ROI_br, cv::Scalar(0, 0, 255), 1);
- if (debug) printf("-------------------------------------****------ roiF top=【%d, %d】 \n", top.x, top.y);
- if (debug) imshow("ROI", ROIcanvas);
- if (debug) imshow("ROI_canvas", canvas);
- //ROIcanvas.copyTo(canvas);
-
-
- //cv::Rect roi_(ROI_tl.x, ROI_tl.y, ROI_br.x - ROI_tl.x, ROI_br.y - ROI_tl.y);
- //if(!ROI_flag) canvas.copyTo(canvas);
- //else canvas = canvas(roi_); //裁剪出的ROI区域
-
- if (result) lockCanvas.copyTo(canvas);
- cv::putText(canvas, to_string(result), cv::Point(30, 65), cv::FONT_HERSHEY_COMPLEX, 1.75, cv::Scalar(255, 135, 160), 3);
- return result;
- }
调用main:
- // 内角:arcPlusLine_ROI 类似金波(金波优化版)
- int main/*arcl*/() {
- bool flag = false;
- //std::string filePath = "E://vsproject//压力罐\\img\\类金波/top";
- std::string filePath = "E://vsproject//压力罐\\img\\类金波";
- //std::string filePath = "E://vsproject//压力罐\\img\\叶子";
- //std::string filePath = "../img/ThreadedRoundPipe/0530img";
-
-
- string resPath = "/output";
- //string resPath = filePath + "./output";
-
-
- cv::Point tlP = cv::Point(200, 340);
- cv::Point brP = cv::Point(950, 999);
- cv::Point top(90, 90);
- std::vector<cv::Point> allPntList;
- cv::Mat canvas;
- PTank_imgProcess m_ImageProcessing;
- //ImageProcess m_ImageProcessing;
- ofstream ofs("log.txt", ios::out);
- if (ofs)
- {
- ofs.clear();
- ofs << "日志启动" << endl;
- }
-
- vector<string> path_name;
- bool lineOnTop = !true;
-
-
- bool getROI = true;
- bool lianxu = false; //循环测试
-
- if (!lianxu)
- {
- string name = cv::format("\\Image_20240627151014832.png");
- string path = filePath + name;
- cv::Mat src = cv::imread(path);
- src.copyTo(canvas);
- cv::namedWindow("main_OriginalIMG", cv::RECURS_FILTER);
- cvSetMouseCallback("main_OriginalIMG", on_mouse_singleClick, 0);
- cv::imshow("main_OriginalIMG", src);
-
- cv::Rect ROI = cv::Rect(0, 0, src.cols, src.rows);
- //cv::Rect ROI = cv::Rect(tlP.x, tlP.y, brP.x - tlP.x, brP.y - tlP.y);
- if (getROI) ROI = getROIFromString(name);
-
-
- bool flag = m_ImageProcessing.arcPlusLine_ROI(src, ROI, top, allPntList, canvas, lineOnTop, true);
-
- cout << "\nmain ==== flag " << flag << endl;
- if (flag) {
- cout << "top = " << top.x << " " << top.y << endl;
- }
- canvas.copyTo(src);
- //cout << "\nmain ==== i " << endl;
- circle(canvas, top, 63, cv::Scalar(0, 69, 255), 1);
- cv::putText(src, to_string(flag), cv::Point(src.cols / 2 - 20, src.rows / 2 - 165), cv::FONT_HERSHEY_COMPLEX, 1.75, cv::Scalar(255, 135, 160), 3);
- cv::namedWindow("main-结果图src", cv::RECURS_FILTER);
- cvSetMouseCallback("main-结果图src", on_mouse_singleClick, 0);
- cv::imshow("main-结果图src", src);
- }
- else
- {
- vector<string> path_name;
- getAllFiles(filePath, path_name);
- cout << "path_name.size()=" << path_name.size() << endl;
-
- int number = 1;
- for (auto i : path_name)
- {
- if (i.find("_res") != std::string::npos) continue;
- if (i.find("png") == std::string::npos && i.find("bmp") == std::string::npos && i.find("jpg") == std::string::npos) continue;
- cv::Mat src = cv::imread(filePath + "\\" + i);
- cout << endl << "number【" << number << "】src path=" << i << " ;" << endl;
- src.copyTo(canvas);
- cv::imshow("main_OriginalIMG", src);
-
- //将结果图写入文件方便查看结果
- int len = filePath.length();
- //i = i.substr(i.find_last_of('\\') + 1, len);
- cout << "i=" << i << endl;
- int time_start = clock();
- int time_end = clock();
-
- cv::Rect ROI = cv::Rect(0, 0, src.cols, src.rows);
- //cv::Rect ROI = cv::Rect(tlP.x, tlP.y, brP.x - tlP.x, brP.y - tlP.y);
- if (getROI) ROI = getROIFromString(i);
-
-
- bool flag = m_ImageProcessing.arcPlusLine_ROI(src, ROI, top, allPntList, canvas, lineOnTop, false);
-
-
- time_end = clock();
- printf("\n耗时 %d ms \n", time_end - time_start);
- cout << "\nmain ==== flag " << flag << endl;
- if (flag) {
- cout << "top = " << top.x << " " << top.y << endl;
- }
- canvas.copyTo(src);
- cv::putText(src, to_string(flag), cv::Point(src.cols / 2 - 20, src.rows / 2 - 65), cv::FONT_HERSHEY_COMPLEX, 1.75, cv::Scalar(255, 135, 160), 3);
- cv::imshow("main-结果图src", src);
- cv::waitKey(10);
-
-
- //将结果图写入文件方便查看结果
- char* filePath_ = new char[len + 1];
- strcpy(filePath_, filePath.c_str());
-
- len = filePath.length();
- char* resPath_ = new char[len + 1];
- strcpy(resPath_, resPath.c_str());
- //i.erase(0, strlen(filePath_) - strlen(resPath_) - 2);
-
- string out = filePath + resPath;
- cout << "\nmain ==== i " << i << endl;
- out.append("\\").append(i);
-
- cout << "number【" << number << "】res path=" << out << endl;
- cv::imwrite(out, src);
- number++;
-
- cout << "path_name.size() = " << path_name.size() << endl;
- cout << "*********************************************************************************************************************" << endl;
- if (number == path_name.size()) break;
- }
- }
- cout << "main 循环结束!!!" << endl;
-
- ofs.close();
- cv::waitKey(0);
- system("Pause");
- return 0;
- }
- bool ImageProcessingTest::ThreadedRoundPipe_ROI(cv::Mat img, cv::Rect ROI, cv::Point& top, cv::Point& bottom, cv::Mat & canvas, bool debug)
- {
- int endRes = 0;
- bool result = false;
- img.copyTo(canvas);
- top = cv::Point(0, 0);
- bottom = cv::Point(0, 0);
-
- cv::Mat imgOriginal;
- bool ROI_flag;//是否有给信息区
- cv::Point ROI_tl = cv::Point2i(ROI.x, ROI.y);
- cv::Point ROI_br = cv::Point2i(ROI.x + ROI.width, ROI.y + ROI.height);
- if (ROI_tl == cv::Point(0, 0) && ROI_br == cv::Point(0, 0) || ROI.width == 0 || ROI.height == 0)
- {
- img.copyTo(imgOriginal);
- ROI_flag = false;
- }
- else
- {
- if (ROI_tl.x > ROI_br.x || ROI_tl.y > ROI_br.y)//信息区两点疑似传反
- {
- printf("信息区两点疑似传反!");
- return false;
- }
- if (ROI_tl.x < 0 || ROI_br.x > img.cols || ROI_tl.y < 0 || ROI_br.y > img.rows)//信息区的框选超出图像范围
- {
- printf("信息区的框选超出图像范围!");
- return false;
- }
- if (abs(ROI_tl.x - ROI_br.x) > img.cols || abs(ROI_tl.y - ROI_br.y) > img.rows)//信息区大小超出图像大小
- {
- printf("信息区大小超出图像大小!");
- return false;
- }
-
- //此时不合法的ROI都已提前返回false
-
- cv::Rect roi(ROI_tl.x, ROI_tl.y, ROI_br.x - ROI_tl.x, ROI_br.y - ROI_tl.y);
- imgOriginal = img(roi); //裁剪出的ROI区域放于imgOriginal
- ROI_flag = true;
- }
-
- result = ThreadedRoundPipe(imgOriginal, top, bottom, canvas, debug);//调用识别算法
-
- if (debug) printf("-------------------------------------****------ roiF top=【%d, %d】, bottom=【%d, %d】\n", top.x, top.y, bottom.x, bottom.y);
- //img.copyTo(canvas);
-
-
- x值和y值补上ROI左上点x和y
- //if (ROI_flag) {
- // if (Corner != cv::Point(0, 0))
- // {
- // Corner.x += ROI_tl.x;
- // Corner.y += ROI_tl.y;
- // }
- //}
-
- img.copyTo(canvas);//调试时注释掉
-
- cv::Mat t1;
- //canvas.convertTo(t1, -1, 900 / 100.0, 200 - 100);//第一次线性变换100
- canvas.convertTo(t1, -1, 900 / 100.0, 200 - 100);//第一次线性变换100
- if (debug)cv::imshow("线性变换ROI", t1);
- t1.copyTo(canvas);
-
- if (result)
- {
- endRes = 1;
- top += ROI_tl;
- bottom += ROI_tl;
- cv::putText(canvas, "true", { cv::Point(50, 50) }, cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(255, 255, 255), 1);
- int w = 38;
- int thickness = 4;
- cv::Point curPoint = top;
- cv::line(canvas, curPoint, cv::Point(curPoint.x - w, curPoint.y), cv::Scalar(235, 135, 40), thickness);
- curPoint = bottom;
- cv::line(canvas, curPoint, cv::Point(curPoint.x - w, curPoint.y), cv::Scalar(235, 135, 40), thickness);
- circle(canvas, top, 2, cv::Scalar(0, 69, 255), -1);
- circle(canvas, top, 63, cv::Scalar(0, 169, 255), 1);
- circle(canvas, bottom, 2, cv::Scalar(0, 69, 255), -1);
- circle(canvas, bottom, 43, cv::Scalar(255, 169, 0), 1);
- }
- else
- {
- cv::putText(canvas, "false", { cv::Point(50, 50) }, cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(255, 255, 255), 1);
- }
-
-
- cv::Mat ROIcanvas;
- img.copyTo(ROIcanvas);
- if (debug) circle(ROIcanvas, top, 3, cv::Scalar(0, 69, 255), 1);
- if (debug) circle(ROIcanvas, top, 63, cv::Scalar(0, 169, 255), 1);
- if (debug) circle(ROIcanvas, bottom, 3, cv::Scalar(0, 69, 255), 1);
- if (debug) circle(ROIcanvas, bottom, 63, cv::Scalar(0, 169, 255), 1);
- if (debug) rectangle(ROIcanvas, ROI_tl, ROI_br, cv::Scalar(0, 0, 255), 1);
- rectangle(canvas, ROI_tl, ROI_br, cv::Scalar(0, 0, 255), 1);
- if (debug) printf("-------------------------------------****------ roiF top=【%d, %d】, bottom=【%d, %d】\n", top.x, top.y, bottom.x, bottom.y);
- if (debug) imshow("ROI", ROIcanvas);
- if (debug) imshow("ROI_canvas", canvas);
- //ROIcanvas.copyTo(canvas);
-
-
- //cv::Rect roi_(ROI_tl.x, ROI_tl.y, ROI_br.x - ROI_tl.x, ROI_br.y - ROI_tl.y);
- //if(!ROI_flag) canvas.copyTo(canvas);
- //else canvas = canvas(roi_); //裁剪出的ROI区域
-
- return result;
- }
调用main:
- //螺纹圆管:ThreadedRoundPipe_ROI
- int main222() {
- bool flag = false;
- //std::string filePath = "E:\\vsproject\\勋仪交接\\标克艾芬达暖水管/0529img";
- //std::string filePath = "../img/ThreadedRoundPipe/0530img";
- std::string filePath = "../img/ThreadedRoundPipe/0606img";
-
-
- string resPath = "/output";
- //string resPath = filePath + "./output";
-
-
- cv::Point tlP = cv::Point(200, 340);
- cv::Point brP = cv::Point(950, 999);
- cv::Point top(90, 90);
- cv::Point bottom(90, 90);
- cv::Mat canvas;
- ImageProcessingTest m_ImageProcessing;
- ofstream ofs("log.txt", ios::out);
- if (ofs)
- {
- ofs.clear();
- ofs << "日志启动" << endl;
- }
-
- vector<string> path_name;
-
-
- bool lianxu = false; //循环测试
-
- if (!lianxu)
- {
- //string path = filePath + cv::format("\\Image_20230606135229441.png");
- string path = filePath + cv::format("\\Image_20230606135308519.png");
- //string path = filePath + cv::format("\\Image_20230601143638388.png");
- //string path = filePath + cv::format("\\Image_20230601143505168.png");
- //string path = filePath + cv::format("\\Image_20230529095011455.png");
- cv::Mat src = cv::imread(path);
- src.copyTo(canvas);
- cv::namedWindow("main_OriginalIMG", cv::RECURS_FILTER);
- cvSetMouseCallback("main_OriginalIMG", on_mouse_singleClick, 0);
- cv::imshow("main_OriginalIMG", src);
-
- //cv::Rect ROI = cv::Rect(0, 0, src.cols, src.rows);
- cv::Rect ROI = cv::Rect(tlP.x, tlP.y, brP.x - tlP.x, brP.y - tlP.y);
-
-
- bool flag = m_ImageProcessing.ThreadedRoundPipe_ROI(src, ROI, top, bottom, canvas, true);
-
- cout << "\nmain ==== flag " << flag << endl;
- if (flag) {
- cout << "top = " << top.x << " " << top.y << endl;
- cout << "bottom = " << bottom.x << " " << bottom.y << endl;
- }
- canvas.copyTo(src);
- //cout << "\nmain ==== i " << endl;
- circle(canvas, top, 63, cv::Scalar(0, 69, 255), 1);
- circle(canvas, bottom, 63, cv::Scalar(0, 69, 255), 1);
- cv::putText(src, to_string(flag), cv::Point(src.cols / 2 - 20, src.rows / 2 - 65), cv::FONT_HERSHEY_COMPLEX, 1.75, cv::Scalar(255, 135, 160), 3);
- cv::namedWindow("main-结果图src", cv::RECURS_FILTER);
- cvSetMouseCallback("main-结果图src", on_mouse_singleClick, 0);
- cv::imshow("main-结果图src", src);
- }
- else
- {
- vector<string> path_name;
- getAllFiles(filePath, path_name);
- cout << "path_name.size()=" << path_name.size() << endl;
-
- int number = 1;
- for (auto i : path_name)
- {
- cv::Mat src = cv::imread(filePath + "\\" + i);
- cout << endl << "number【" << number << "】src path=" << i << " ;" << endl;
- src.copyTo(canvas);
- cv::imshow("main_OriginalIMG", src);
-
- //将结果图写入文件方便查看结果
- int len = filePath.length();
- //i = i.substr(i.find_last_of('\\') + 1, len);
- cout << "i=" << i << endl;
- int time_start = clock();
- int time_end = clock();
-
- //cv::Rect ROI = cv::Rect(0, 0, src.cols, src.rows);
- cv::Rect ROI = cv::Rect(tlP.x, tlP.y, brP.x - tlP.x, brP.y - tlP.y);
-
-
- bool flag = m_ImageProcessing.ThreadedRoundPipe_ROI(src, ROI, top, bottom, canvas, false);
-
-
- time_end = clock();
- printf("\n耗时 %d ms \n", time_end - time_start);
- cout << "\nmain ==== flag " << flag << endl;
- if (flag) {
- cout << "top = " << top.x << " " << top.y << endl;
- cout << "bottom = " << bottom.x << " " << bottom.y << endl;
- }
- canvas.copyTo(src);
- cv::putText(src, to_string(flag), cv::Point(src.cols / 2 - 20, src.rows / 2 - 65), cv::FONT_HERSHEY_COMPLEX, 1.75, cv::Scalar(255, 135, 160), 3);
- cv::imshow("main-结果图src", src);
- cv::waitKey(10);
-
-
- //将结果图写入文件方便查看结果
- char* filePath_ = new char[len + 1];
- strcpy(filePath_, filePath.c_str());
-
- len = filePath.length();
- char* resPath_ = new char[len + 1];
- strcpy(resPath_, resPath.c_str());
- //i.erase(0, strlen(filePath_) - strlen(resPath_) - 2);
-
- string out = filePath + resPath;
- cout << "\nmain ==== i " << i << endl;
- out.append("\\").append(i);
-
- cout << "number【" << number << "】res path=" << out << endl;
- cv::imwrite(out, src);
- number++;
-
- cout << "path_name.size() = " << path_name.size() << endl;
- cout << "*********************************************************************************************************************" << endl;
- if (number == path_name.size()) break;
- }
- }
- cout << "main 循环结束!!!" << endl;
-
- ofs.close();
- cv::waitKey(0);
- system("Pause");
- return 0;
- }
- /*
- //矩形位置 返回双点+骨干点集
- cv::Mat img, 原图
- cv::Rect ROI,
- cv::Point& top, 输出焊点(图像上位于较上方的点)
- cv::Point& bottom, 输出焊点(图像上位于较下方的点)
- std::vector<cv::Point>& allPntList:直线部分非弧线的点集
- cv::Mat &canvas,效果图可视化
- */
- bool rectangle2Pnt(cv::Mat imgOriginal, cv::Point& top, cv::Point& bottom, std::vector<cv::Point>& allPntList, cv::Mat &canvas, bool debug = false);
- bool rectangle2Pnt_ROI(cv::Mat img, cv::Rect ROI, cv::Point& top, cv::Point& bottom, std::vector<cv::Point>& allPntList, cv::Mat &canvas, bool debug = false);
- bool PTank_imgProcess::rectangle2Pnt_ROI(cv::Mat img, cv::Rect ROI, cv::Point & top, cv::Point & bottom, std::vector<cv::Point>& allPntList, cv::Mat & canvas, bool debug)
- {
- int endRes = 0;
- bool result = false;
- img.copyTo(canvas);
- top = cv::Point(0, 0);
- bottom = cv::Point(0, 0);
- allPntList.clear();
-
- cv::Mat imgOriginal;
- bool ROI_flag;//是否有给信息区
- cv::Point ROI_tl = cv::Point2i(ROI.x, ROI.y);
- cv::Point ROI_br = cv::Point2i(ROI.x + ROI.width, ROI.y + ROI.height);
- if (ROI_tl == cv::Point(0, 0) && ROI_br == cv::Point(0, 0) || ROI.width == 0 || ROI.height == 0)
- {
- img.copyTo(imgOriginal);
- ROI_flag = false;
- }
- else
- {
- if (ROI_tl.x > ROI_br.x || ROI_tl.y > ROI_br.y)//信息区两点疑似传反
- {
- printf("信息区两点疑似传反!");
- return false;
- }
- if (ROI_tl.x < 0 || ROI_br.x > img.cols || ROI_tl.y < 0 || ROI_br.y > img.rows)//信息区的框选超出图像范围
- {
- printf("信息区的框选超出图像范围!");
- return false;
- }
- if (abs(ROI_tl.x - ROI_br.x) > img.cols || abs(ROI_tl.y - ROI_br.y) > img.rows)//信息区大小超出图像大小
- {
- printf("信息区大小超出图像大小!");
- return false;
- }
-
- //此时不合法的ROI都已提前返回false
-
- cv::Rect roi(ROI_tl.x, ROI_tl.y, ROI_br.x - ROI_tl.x, ROI_br.y - ROI_tl.y);
- imgOriginal = img(roi); //裁剪出的ROI区域放于imgOriginal
- ROI_flag = true;
- }
-
- result = rectangle2Pnt(imgOriginal, top, bottom, allPntList, canvas, debug);//调用识别算法
-
-
- if (debug) printf("-------------------------------------****------ roiF top=【%d, %d】, bottom=【%d, %d】\n", top.x, top.y, bottom.x, bottom.y);
- //img.copyTo(canvas);
-
- img.copyTo(canvas);//调试时注释掉
- if (result)
- {
- endRes = 1;
- top += ROI_tl;
- bottom += ROI_tl;
- for (int i = 0; i < allPntList.size(); i++) {
- allPntList.at(i) += ROI_tl;
- }
- int w = 5;
- for (int i = 0; i < allPntList.size(); i++) {
- cv::Point curPoint = allPntList.at(i);
- cv::line(canvas, curPoint, cv::Point(curPoint.x - w, curPoint.y), cv::Scalar(55, 195, 40), 1);
- }
- cv::putText(canvas, "true", { cv::Point(50, 50) }, cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(255, 255, 255), 1);
- circle(canvas, top, 3, cv::Scalar(0, 69, 255), 1);
- circle(canvas, top, 63, cv::Scalar(0, 169, 255), 1);
- circle(canvas, bottom, 3, cv::Scalar(0, 69, 255), 1);
- circle(canvas, bottom, 43, cv::Scalar(255, 169, 0), 1);
- }
- else
- {
- cv::putText(canvas, "false", { cv::Point(50, 50) }, cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(255, 255, 255), 1);
- }
-
-
- cv::Mat ROIcanvas;
- img.copyTo(ROIcanvas);
- if (debug) circle(ROIcanvas, top, 3, cv::Scalar(0, 69, 255), 1);
- if (debug) circle(ROIcanvas, top, 63, cv::Scalar(0, 169, 255), 1);
- if (debug) circle(ROIcanvas, bottom, 3, cv::Scalar(0, 69, 255), 1);
- if (debug) circle(ROIcanvas, bottom, 63, cv::Scalar(0, 169, 255), 1);
- if (debug) rectangle(ROIcanvas, ROI_tl, ROI_br, cv::Scalar(0, 0, 255), 1);
- rectangle(canvas, ROI_tl, ROI_br, cv::Scalar(0, 0, 255), 1);
- if (debug) printf("-------------------------------------****------ roiF top=【%d, %d】, bottom=【%d, %d】\n", top.x, top.y, bottom.x, bottom.y);
- if (debug) imshow("ROI", ROIcanvas);
- if (debug) imshow("ROI_canvas", canvas);
- //ROIcanvas.copyTo(canvas);
-
- return result;
- }
调用main:
- //矩形位置 返回双点+骨干点集
- int main/*Rectangle2Pnt_ROI*/() {
- bool flag;
- //std::string filePath = "../../../../Log08141641/TestImg/src";
- std::string filePath = "E://vsproject//压力罐\\img\\矩形";
-
-
- string resPath = "/output";
- //string resPath = filePath + "./output";
-
-
- cv::Point tlP = cv::Point(500, 292);
- cv::Point brP = cv::Point(750, 677);
- //cv::Rect ROI = cv::Rect(0, 0, 0, 0);
- //cv::Rect ROI = cv::Rect(0, 0, src.cols, src.rows);
- //cv::Rect ROI = cv::Rect(tlP.x, tlP.y, brP.x - tlP.x, brP.y - tlP.y);
- //cv::Rect ROI = cv::Rect(539, 218, 113, 513);
- cv::Point top(90, 90);
- cv::Point bottom(90, 90);
- int outMidY;
- cv::Mat canvas;
- PTank_imgProcess m_ImageProcessing;
- ofstream ofs("log.txt", ios::out);
- if (ofs)
- {
- ofs.clear();
- ofs << "日志启动" << endl;
- }
- std::vector<cv::Point> allPntList;
- vector<string> path_name;
-
-
- bool getROI = true;
- bool lianxu = false; //循环测试
-
- if (!lianxu)
- {
- string name = cv::format("\\Image_20240627144421072.png");
- string path = filePath + name;
- cv::Mat src = cv::imread(path);
- src.copyTo(canvas);
- cv::namedWindow("main_OriginalIMG", cv::RECURS_FILTER);
- cvSetMouseCallback("main_OriginalIMG", on_mouse_singleClick, 0);
- cv::imshow("main_OriginalIMG", src);
-
- cv::Rect ROI = cv::Rect(0, 0, src.cols, src.rows);
- //cv::Rect ROI = cv::Rect(tlP.x, tlP.y, brP.x - tlP.x, brP.y - tlP.y);
- if (getROI) ROI = getROIFromString(name);
-
-
- bool flag = m_ImageProcessing.rectangle2Pnt_ROI(src, ROI, top, bottom, allPntList, canvas, true);
-
- cout << "\nmain ==== flag " << flag << endl;
- if (flag) {
- cout << "top = " << top.x << " " << top.y << endl;
- cout << "bottom = " << bottom.x << " " << bottom.y << endl;
- }
- canvas.copyTo(src);
- //cout << "\nmain ==== i " << endl;
- circle(canvas, top, 63, cv::Scalar(0, 69, 255), 1);
- circle(canvas, bottom, 63, cv::Scalar(0, 69, 255), 1);
- cv::putText(src, to_string(flag), cv::Point(src.cols / 2 - 20, src.rows / 2 - 65), cv::FONT_HERSHEY_COMPLEX, 1.75, cv::Scalar(255, 135, 160), 3);
- cv::namedWindow("main-结果图src", cv::RECURS_FILTER);
- cvSetMouseCallback("main-结果图src", on_mouse_singleClick, 0);
- cv::imshow("main-结果图src", src);
- cv::namedWindow("main-canvas", cv::RECURS_FILTER);
- cvSetMouseCallback("main-canvas", on_mouse_singleClick, 0);
- cv::imshow("main-canvas", canvas);
- }
- else
- {
- vector<string> path_name;
- getAllFiles(filePath, path_name);
- cout << "path_name.size()=" << path_name.size() << endl;
-
- int number = 1;
- for (auto i : path_name)
- {
- //cout << i.size() << endl;
- if (i.size() == 7) continue;
- if (i.find(".log") != std::string::npos) continue;
- std::string path11 = filePath + "\\" + i;
- cv::Mat src = cv::imread(path11);
- //cv::Mat src = cv::imread(filePath + "\\" + i);
- cout << endl << "number【" << number << "】src path=" << i << " ;" << endl;
- src.copyTo(canvas);
- cv::imshow("main_OriginalIMG", src);
-
- //将结果图写入文件方便查看结果
- int len = filePath.length();
- //i = i.substr(i.find_last_of('\\') + 1, len);
- cout << "i=" << i << ", path11=" << path11 << endl;
- int time_start = clock();
- int time_end = clock();
-
- cv::Rect ROI = cv::Rect(0, 0, src.cols, src.rows);
- //cv::Rect ROI = cv::Rect(tlP.x, tlP.y, brP.x - tlP.x, brP.y - tlP.y);
- if (getROI) ROI = getROIFromString(i);
-
-
- bool flag = m_ImageProcessing.rectangle2Pnt_ROI(src, ROI, top, bottom, allPntList, canvas, false);
-
-
- time_end = clock();
- printf("\n耗时 %d ms \n", time_end - time_start);
- cout << "\nmain ==== flag " << flag << endl;
- if (flag) {
- cout << "top = " << top.x << " " << top.y << endl;
- cout << "bottom = " << bottom.x << " " << bottom.y << endl;
- }
- canvas.copyTo(src);
- cv::putText(src, to_string(flag), cv::Point(src.cols / 2 - 20, src.rows / 2 - 65), cv::FONT_HERSHEY_COMPLEX, 1.75, cv::Scalar(255, 135, 160), 3);
- cv::imshow("main-结果图src", src);
- cv::imshow("main-canvas", canvas);
-
-
- //将结果图写入文件方便查看结果
- char* filePath_ = new char[len + 1];
- strcpy(filePath_, filePath.c_str());
-
- len = filePath.length();
- char* resPath_ = new char[len + 1];
- strcpy(resPath_, resPath.c_str());
- //i.erase(0, strlen(filePath_) - strlen(resPath_) - 2);
-
- string out = filePath + resPath;
- cout << "\nmain ==== i " << i << endl;
- out.append("\\").append(i);
-
- cout << "number【" << number << "】res path=" << out << endl;
- cv::imwrite(out, src);
- number++;
-
- cout << "path_name.size() = " << path_name.size() << endl;
- cout << "*********************************************************************************************************************" << endl;
- cv::waitKey(10);
- }
- cout << "循环结束!!! main " << endl;
- }
-
- ofs.close();
- cv::waitKey(0);
- system("Pause");
- return 0;
- }
注:该接口中 bottom, linearPntB无效!!!
根据传入参数判断是否左右翻转,判断识别的是上半部分还是下半部分,下半部分则需再做上下翻转再进入识别。
- /*
- //D型主管,方形支管 只处理上半部分或下半部分
- cv::Mat img, 原图
- cv::Rect ROI, 可以让右边的干扰直反光落进去,上下不用截,左右可适当截小一下减少识别时的计算时间
- std::vector<cv::Point>& linearPnt:直线部分非弧线的点集
- cv::Point& top, 输出焊点(图像上位于较上方的点)倒角弧形边边上的激光最边边点
- cv::Point& bottom, 输出焊点(图像上位于较下方的点)倒角弧形边边上的激光最边边点
- cv::Mat &canvas,效果图可视化
- bool arcTop_right = true;//圆弧顶点是否朝右的标志量,默认为true(true为朝右,false为朝左)
- bool isTopHalf = true;//识别区域是否为上半部分,上半部分为true,下半部分反之
- 注:该接口中 bottom, linearPntB无效!!!
- */
- bool OneSideSquare(cv::Mat imgOriginal, std::vector<cv::Point>& linearPntT, std::vector<cv::Point>& linearPntB, std::vector<cv::Point>& linearPntM, cv::Point& top, cv::Point& bottom, cv::Mat &canvas, bool debug = false);
- bool OneSideSquare_ROI(cv::Mat img, cv::Rect ROI, std::vector<cv::Point>& linearPntT, std::vector<cv::Point>& linearPntB, std::vector<cv::Point>& linearPntM, cv::Point& top, cv::Point& bottom, cv::Mat &canvas, bool arcTop_right = true, bool isTopHalf = true, bool debug = false);
- bool ImageProcessing::OneSideSquare_ROI(cv::Mat img, cv::Rect ROI, std::vector<cv::Point>& linearPntT, std::vector<cv::Point>& linearPntB, std::vector<cv::Point>& linearPntM, cv::Point & top, cv::Point & bottom, cv::Mat & canvas, bool arcTop_right, bool isTopHalf, bool debug)
- {
- int endRes = 0;
- bool result = false;
- img.copyTo(canvas);
- top = cv::Point(0, 0);
- bottom = cv::Point(0, 0);
- linearPntT.clear();
- linearPntB.clear();
- linearPntM.clear();
-
- cv::Mat imgOriginal;
- bool ROI_flag;//是否有给信息区
- cv::Point ROI_tl = cv::Point2i(ROI.x, ROI.y);
- cv::Point ROI_br = cv::Point2i(ROI.x + ROI.width, ROI.y + ROI.height);
- if (ROI_tl == cv::Point(0, 0) && ROI_br == cv::Point(0, 0) || ROI.width == 0 || ROI.height == 0)
- {
- img.copyTo(imgOriginal);
- ROI_flag = false;
- }
- else
- {
- if (ROI_tl.x > ROI_br.x || ROI_tl.y > ROI_br.y)//信息区两点疑似传反
- {
- printf("信息区两点疑似传反!");
- return false;
- }
- if (ROI_tl.x < 0 || ROI_br.x > img.cols || ROI_tl.y < 0 || ROI_br.y > img.rows)//信息区的框选超出图像范围
- {
- printf("信息区的框选超出图像范围!");
- return false;
- }
- if (abs(ROI_tl.x - ROI_br.x) > img.cols || abs(ROI_tl.y - ROI_br.y) > img.rows)//信息区大小超出图像大小
- {
- printf("信息区大小超出图像大小!");
- return false;
- }
-
- //此时不合法的ROI都已提前返回false
-
- cv::Rect roi(ROI_tl.x, ROI_tl.y, ROI_br.x - ROI_tl.x, ROI_br.y - ROI_tl.y);
- imgOriginal = img(roi); //裁剪出的ROI区域放于imgOriginal
- ROI_flag = true;
- }
-
- if (arcTop_right) {//圆弧顶点朝右的情况
- if (isTopHalf) {
- result = OneSideSquare(imgOriginal, linearPntT, linearPntB, linearPntM, top, bottom, canvas, debug);//调用识别算法
- }
- else {
- cv::Mat fpMt;
- cv::flip(imgOriginal, fpMt, 0); // 上下翻转 x对称
- result = OneSideSquare(fpMt, linearPntT, linearPntB, linearPntM, top, bottom, canvas, debug);//调用识别算法
- if (result) {
- top.y = fpMt.rows - top.y - 1;
- for (int i = 0; i < linearPntT.size(); i++) {
- linearPntT.at(i).y = fpMt.rows - linearPntT.at(i).y - 1;
- }
- for (int i = 0; i < linearPntM.size(); i++) {
- linearPntM.at(i).y = fpMt.rows - linearPntM.at(i).y - 1;
- }
- }
- }
- }
- else {//圆弧顶点朝左的情况
- cv::Mat flipMat;
- cv::flip(imgOriginal, flipMat, 1); // 左右翻转 y对称
- if (debug) imshow("图像左右翻转", flipMat);
-
- if (isTopHalf) {
- result = OneSideSquare(flipMat, linearPntT, linearPntB, linearPntM, top, bottom, canvas, debug);//调用识别算法
- }
- else {
- cv::Mat fpMt;
- cv::flip(flipMat, fpMt, 0); // 上下翻转 x对称
- result = OneSideSquare(fpMt, linearPntT, linearPntB, linearPntM, top, bottom, canvas, debug);//调用识别算法
- if (result) {
- top.y = fpMt.rows - top.y - 1;
- for (int i = 0; i < linearPntT.size(); i++) {
- linearPntT.at(i).y = fpMt.rows - linearPntT.at(i).y - 1;
- }
- for (int i = 0; i < linearPntM.size(); i++) {
- linearPntM.at(i).y = fpMt.rows - linearPntM.at(i).y - 1;
- }
- }
- }
-
- if (result) {
- top.x = flipMat.cols - top.x - 1;
- //bottom.x = flipMat.cols - bottom.x - 1;
- for (int i = 0; i < linearPntT.size(); i++) {
- linearPntT.at(i).x = flipMat.cols - linearPntT.at(i).x - 1;
- }
- for (int i = 0; i < linearPntB.size(); i++) {
- linearPntB.at(i).x = flipMat.cols - linearPntB.at(i).x - 1;
- }
- for (int i = 0; i < linearPntM.size(); i++) {
- linearPntM.at(i).x = flipMat.cols - linearPntM.at(i).x - 1;
- }
- }
- }
-
-
- if (debug) printf("-------------------------------------****------ roiF top=【%d, %d】, bottom=【%d, %d】\n", top.x, top.y, bottom.x, bottom.y);
- //img.copyTo(canvas);
-
-
- x值和y值补上ROI左上点x和y
- //if (ROI_flag) {
- // if (Corner != cv::Point(0, 0))
- // {
- // Corner.x += ROI_tl.x;
- // Corner.y += ROI_tl.y;
- // }
- //}
-
- img.copyTo(canvas);//调试时注释掉
- if (result)
- {
- endRes = 1;
- top += ROI_tl;
- //bottom += ROI_tl;
- for (int i = 0; i < linearPntT.size(); i++) {
- linearPntT.at(i) += ROI_tl;
- }
- for (int i = 0; i < linearPntB.size(); i++) {
- linearPntB.at(i) += ROI_tl;
- }
- for (int i = 0; i < linearPntM.size(); i++) {
- linearPntM.at(i) += ROI_tl;
- }
- for (int i = 0; i < linearPntT.size(); i++) {
- cv::Point curPoint = linearPntT.at(i);
- cv::line(canvas, curPoint, cv::Point(curPoint.x - 5, curPoint.y), cv::Scalar(55, 195, 40), 1);
- }
- for (int i = 0; i < linearPntB.size(); i++) {
- cv::Point curPoint = linearPntB.at(i);
- cv::line(canvas, curPoint, cv::Point(curPoint.x - 5, curPoint.y), cv::Scalar(55, 195, 40), 1);
- }
- for (int i = 0; i < linearPntM.size(); i++) {
- cv::Point curPoint = linearPntM.at(i);
- cv::line(canvas, curPoint, cv::Point(curPoint.x - 5, curPoint.y), cv::Scalar(145, 175, 40), 1);
- }
- cv::putText(canvas, "true", { cv::Point(50, 50) }, cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(255, 255, 255), 1);
- circle(canvas, top, 3, cv::Scalar(0, 69, 255), 1);
- circle(canvas, top, 63, cv::Scalar(0, 169, 255), 1);
- //circle(canvas, bottom, 3, cv::Scalar(0, 69, 255), 1);
- //circle(canvas, bottom, 43, cv::Scalar(255, 169, 0), 1);
- }
- else
- {
- cv::putText(canvas, "false", { cv::Point(50, 50) }, cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(255, 255, 255), 1);
- }
-
-
- cv::Mat ROIcanvas;
- img.copyTo(ROIcanvas);
- if (debug) circle(ROIcanvas, top, 3, cv::Scalar(0, 69, 255), 1);
- if (debug) circle(ROIcanvas, top, 63, cv::Scalar(0, 169, 255), 1);
- //if (debug) circle(ROIcanvas, bottom, 3, cv::Scalar(0, 69, 255), 1);
- //if (debug) circle(ROIcanvas, bottom, 63, cv::Scalar(0, 169, 255), 1);
- if (debug) rectangle(ROIcanvas, ROI_tl, ROI_br, cv::Scalar(0, 0, 255), 1);
- rectangle(canvas, ROI_tl, ROI_br, cv::Scalar(0, 0, 255), 1);
- if (debug) printf("-------------------------------------****------ roiF top=【%d, %d】, bottom=【%d, %d】\n", top.x, top.y, bottom.x, bottom.y);
- if (debug) imshow("ROI", ROIcanvas);
- if (debug) imshow("ROI_canvas", canvas);
- //ROIcanvas.copyTo(canvas);
-
- return result;
- }
调用main:
- //D型主管,方形支管 上或下单侧 OneSideSquare_ROI
- int main() {
- bool flag;
- //std::string filePath = "../../../../0方管支管/1023img";
- std::string filePath = "../../../../0方管支管/left";
- //std::string filePath = "../../../../0方管支管/right";
-
-
- string resPath = "/output";
- //string resPath = filePath + "./output";
-
-
- //cv::Point tlP = cv::Point(500, 40);
- //cv::Point brP = cv::Point(750, 777);
- cv::Point tlP = cv::Point(584, 236);
- cv::Point brP = cv::Point(660, 820);
- //cv::Rect ROI = cv::Rect(0, 0, 0, 0);
- //cv::Rect ROI = cv::Rect(0, 0, src.cols, src.rows);
- //cv::Rect ROI = cv::Rect(tlP.x, tlP.y, brP.x - tlP.x, brP.y - tlP.y);
- //cv::Rect ROI = cv::Rect(639, 188, 125, 569);
- cv::Point top(90, 90);
- cv::Point bottom(90, 90);
- cv::Point2f midP(90, 90);
- int outMidY;
- cv::Mat canvas;
- ImageProcessing m_ImageProcessing;
- ofstream ofs("log.txt", ios::out);
- if (ofs)
- {
- ofs.clear();
- ofs << "日志启动" << endl;
- }
- std::vector<cv::Point> linearPntT;
- std::vector<cv::Point> linearPntB;
- std::vector<cv::Point> linearPntM;
- vector<Picture_set> img_buf;
- vector<string> path_name;
- bool arcTop_right = !true;
- bool isTopHalf = true;
- int midyTolerant = 4;
-
- bool getROI = true;
- bool lianxu = false; //循环测试
-
- if (lianxu)
- {
- //string path = filePath + cv::format("\\Image_20231023105829348.png");
- //std::string name = cv::format("\\ImgD_2023_10_26_10_48_12_135_567_196_153_603_Src.png");
- std::string name = cv::format("\\ImgD_2023_10_25_18_16_24_519_569_200_166_559_Src.png");
- string path = filePath + name;
- cv::Mat src = cv::imread(path);
- src.copyTo(canvas);
- cv::namedWindow("main_OriginalIMG", cv::NORMCONV_FILTER);
- cvSetMouseCallback("main_OriginalIMG", on_mouse_singleClick, 0);
- cv::imshow("main_OriginalIMG", src);
-
- //cv::Rect ROI = cv::Rect(0, 0, src.cols, src.rows);
- cv::Rect ROI = cv::Rect(tlP.x, tlP.y, brP.x - tlP.x, brP.y - tlP.y);
- if (getROI) {
- ROI = getROIFromString(name);
- ROI.height /= 2;
- if (!isTopHalf) {
- ROI.y += ROI.height;
- }
- }
-
- //鼠标点击的坐标【691, 319】
- // 鼠标点击的坐标【692, 632】
- //cout << src.size() << endl;
- //rotateImage(src);
- //cout << src.size() << endl;
- //鼠标点击的坐标【707, 691】
- // 鼠标点击的坐标【395, 691】
- //trueX=outY;
- //trueY=oriSrc.rows-outX;
- //circle(src, cv::Point(622, 424), 5, cv::Scalar(255, 255, 255), -1);
- //cv::Mat flipMat;
- //cv::flip(src, flipMat, 1);
- //cv::Point q = cv::Point(flipMat.cols - 622 - 1, 424)/* - cv::Point(546, 228)*/;
- //circle(flipMat, q, 3, cv::Scalar(0, 0, 0), -1);
- //cv::imshow("flipMat", flipMat);
- //cv::waitKey();
- //cv::flip(src, src, 0);
-
- bool flag = m_ImageProcessing.OneSideSquare_ROI(src, ROI, linearPntT, linearPntB, linearPntM, top, bottom, canvas, arcTop_right, isTopHalf, true);
-
- cout << "\nmain ==== flag " << flag << endl;
- if (flag) {
- cout << "top = " << top.x << " " << top.y << endl;
- cout << "bottom = " << bottom.x << " " << bottom.y << endl;
- }
- canvas.copyTo(src);
- //cout << "\nmain ==== i " << endl;
- circle(canvas, top, 63, cv::Scalar(0, 69, 255), 1);
- circle(canvas, bottom, 63, cv::Scalar(0, 69, 255), 1);
- cv::putText(src, to_string(flag), cv::Point(src.cols / 2 - 20, src.rows / 2 - 65), cv::FONT_HERSHEY_COMPLEX, 1.75, cv::Scalar(255, 135, 160), 3);
- cv::namedWindow("main-结果图src", cv::RECURS_FILTER);
- cvSetMouseCallback("main-结果图src", on_mouse_singleClick, 0);
- cv::imshow("main-结果图src", src);
- cv::namedWindow("main-canvas", cv::RECURS_FILTER);
- cvSetMouseCallback("main-canvas", on_mouse_singleClick, 0);
- cv::imshow("main-canvas", canvas);
- }
- else
- {
- vector<string> path_name;
- getAllFiles(filePath, path_name);
- cout << "path_name.size()=" << path_name.size() << endl;
-
- int number = 1;
- for (auto i : path_name)
- {
- //cout << i.size() << endl;
- if (i.size() == 7) continue;
- if (i.find(".log") != std::string::npos) continue;
- if (i.find(".txt") != std::string::npos) continue;
- std::string name = i;
- std::string path11 = filePath + "\\" + i;
- cv::Mat src = cv::imread(path11);
- //cv::Mat src = cv::imread(filePath + "\\" + i);
- cout << endl << "number【" << number << "】src path=" << i << " ;" << endl;
- src.copyTo(canvas);
- cv::imshow("main_OriginalIMG", src);
-
- //将结果图写入文件方便查看结果
- int len = filePath.length();
- //i = i.substr(i.find_last_of('\\') + 1, len);
- cout << "i=" << i << ", path11=" << path11 << endl;
- int time_start = clock();
- int time_end = clock();
-
- cv::Rect ROI = cv::Rect(0, 0, src.cols, src.rows);
- cv::Rect ROI = cv::Rect(tlP.x, tlP.y, brP.x - tlP.x, brP.y - tlP.y);
- if (getROI) {
- ROI = getROIFromString(name);
- ROI.height /= 2;
- if (!isTopHalf) {
- ROI.y += ROI.height;
- }
- }
-
- bool flag = m_ImageProcessing.OneSideSquare_ROI(src, ROI, linearPntT, linearPntB, linearPntM, top, bottom, canvas, arcTop_right, isTopHalf, false);
-
-
- time_end = clock();
- printf("\n耗时 %d ms \n", time_end - time_start);
- cout << "\nmain ==== flag " << flag << endl;
- if (flag) {
- cout << "top = " << top.x << " " << top.y << endl;
- cout << "bottom = " << bottom.x << " " << bottom.y << endl;
- }
- canvas.copyTo(src);
- cv::putText(src, to_string(flag), cv::Point(src.cols / 2 - 20, src.rows / 2 - 65), cv::FONT_HERSHEY_COMPLEX, 1.75, cv::Scalar(255, 135, 160), 3);
- cv::imshow("main-结果图src", src);
- cv::imshow("main-canvas", canvas);
-
-
- //将结果图写入文件方便查看结果
- char* filePath_ = new char[len + 1];
- strcpy(filePath_, filePath.c_str());
-
- len = filePath.length();
- char* resPath_ = new char[len + 1];
- strcpy(resPath_, resPath.c_str());
- //i.erase(0, strlen(filePath_) - strlen(resPath_) - 2);
-
- string out = filePath + resPath;
- cout << "\nmain ==== i " << i << endl;
- out.append("\\").append(i);
-
- cout << "number【" << number << "】res path=" << out << endl;
- cv::imwrite(out, src);
- number++;
-
- cout << "path_name.size() = " << path_name.size() << endl;
- cout << "*********************************************************************************************************************" << endl;
- cv::waitKey(10);
- }
- cout << "循环结束!!! main " << endl;
- }
-
- ofs.close();
- cv::waitKey(0);
- system("Pause");
- return 0;
- }
- /*
- //两弧线夹圆弧 返回三点+骨干点集
- cv::Mat img, 原图
- cv::Rect ROI,
- cv::Point& top, 输出焊点(图像上位于较上方的点)
- cv::Point& bottom, 输出焊点(图像上位于较下方的点)
- cv::Point2f& midP, 圆弧中点
- std::vector<cv::Point>& allPntList:直线部分非弧线的点集
- cv::Mat &canvas,效果图可视化
- */
- bool twoArcsClipTheArc(cv::Mat imgOriginal, cv::Point& top, cv::Point& bottom, cv::Point2f& midP, std::vector<cv::Point>& allPntList, cv::Mat &canvas, bool debug = false);
- bool twoArcsClipTheArc_ROI(cv::Mat img, cv::Rect ROI, cv::Point& top, cv::Point& bottom, cv::Point2f& midP, std::vector<cv::Point>& allPntList, cv::Mat &canvas, bool arcTop_right = true, bool debug = false);
- bool PTank_imgProcess::twoArcsClipTheArc_ROI(cv::Mat img, cv::Rect ROI, cv::Point & top, cv::Point & bottom, cv::Point2f & midP, std::vector<cv::Point>& allPntList, cv::Mat & canvas, bool arcTop_right, bool debug)
- {
- int endRes = 0;
- bool result = false;
- img.copyTo(canvas);
- top = cv::Point(0, 0);
- bottom = cv::Point(0, 0);
- midP = cv::Point2f(0, 0);
- allPntList.clear();
-
- cv::Mat imgOriginal;
- bool ROI_flag;//是否有给信息区
- cv::Point ROI_tl = cv::Point2i(ROI.x, ROI.y);
- cv::Point ROI_br = cv::Point2i(ROI.x + ROI.width, ROI.y + ROI.height);
- if (ROI_tl == cv::Point(0, 0) && ROI_br == cv::Point(0, 0) || ROI.width == 0 || ROI.height == 0)
- {
- img.copyTo(imgOriginal);
- ROI_flag = false;
- }
- else
- {
- if (ROI_tl.x > ROI_br.x || ROI_tl.y > ROI_br.y)//信息区两点疑似传反
- {
- printf("信息区两点疑似传反!");
- return false;
- }
- if (ROI_tl.x < 0 || ROI_br.x > img.cols || ROI_tl.y < 0 || ROI_br.y > img.rows)//信息区的框选超出图像范围
- {
- printf("信息区的框选超出图像范围!");
- return false;
- }
- if (abs(ROI_tl.x - ROI_br.x) > img.cols || abs(ROI_tl.y - ROI_br.y) > img.rows)//信息区大小超出图像大小
- {
- printf("信息区大小超出图像大小!");
- return false;
- }
-
- //此时不合法的ROI都已提前返回false
-
- cv::Rect roi(ROI_tl.x, ROI_tl.y, ROI_br.x - ROI_tl.x, ROI_br.y - ROI_tl.y);
- imgOriginal = img(roi); //裁剪出的ROI区域放于imgOriginal
- ROI_flag = true;
- }
-
- if (arcTop_right) {//圆弧顶点朝右的情况
- result = twoArcsClipTheArc(imgOriginal, top, bottom, midP, allPntList, canvas, debug);//调用识别算法
- }
- else {//圆弧顶点朝左的情况
- cv::Mat flipMat;
- cv::flip(imgOriginal, flipMat, 1); // 左右翻转 y对称
- if (debug) imshow("图像左右翻转", flipMat);
- result = twoArcsClipTheArc(flipMat, top, bottom, midP, allPntList, canvas, debug);//调用识别算法
- if (result) {
- top.x = flipMat.cols - top.x - 1;
- bottom.x = flipMat.cols - bottom.x - 1;
- for (int i = 0; i < allPntList.size(); i++) {
- allPntList.at(i).x = flipMat.cols - allPntList.at(i).x - 1;
- }
- if (midP != cv::Point2f(0, 0)) midP.x = flipMat.cols - midP.x - 1;
- }
- }
-
-
- if (debug) printf("-------------------------------------****------ roiF top=【%d, %d】, bottom=【%d, %d】\n", top.x, top.y, bottom.x, bottom.y);
- if (debug) printf(" roiF midP=【%f, %f】\n", midP.x, midP.y);
- //img.copyTo(canvas);
-
- //img.copyTo(canvas);//调试时注释掉
- if (result)
- {
- endRes = 1;
- for (int i = 0; i < allPntList.size(); i++) {
- allPntList.at(i) += ROI_tl;
- }
- for (int i = 0; i < allPntList.size(); i++) {
- cv::Point curPoint = allPntList.at(i);
- cv::line(canvas, curPoint, cv::Point(curPoint.x - 5, curPoint.y), cv::Scalar(55, 195, 40), 1);
- }
- top += ROI_tl;
- bottom += ROI_tl;
- midP += cv::Point2f(ROI_tl);
- //if (midP != cv::Point2f(0, 0)) {
- // midP.x = midP.x + ROI_tl.x;
- // midP.y = midP.y + ROI_tl.y;
- //}
- circle(canvas, midP, 3, cv::Scalar(0, 69, 255), 1);
- circle(canvas, midP, 43, cv::Scalar(0, 169, 255), 1);
- cv::line(canvas, midP, cv::Point2f(5, midP.y), cv::Scalar(155, 195, 40), 1);
- cv::line(canvas, cv::Point2f(midP.x, midP.y - 5), cv::Point2f(midP.x, midP.y + 5), cv::Scalar(155, 195, 40), 1);
- cv::putText(canvas, "true", { cv::Point(50, 50) }, cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(255, 255, 255), 1);
- circle(canvas, top, 3, cv::Scalar(0, 69, 255), 1);
- circle(canvas, top, 63, cv::Scalar(0, 169, 255), 1);
- circle(canvas, bottom, 3, cv::Scalar(0, 69, 255), 1);
- circle(canvas, bottom, 43, cv::Scalar(255, 169, 0), 1);
- }
- else
- {
- cv::putText(canvas, "false", { cv::Point(50, 50) }, cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(255, 255, 255), 1);
- }
-
-
- cv::Mat ROIcanvas;
- img.copyTo(ROIcanvas);
- if (debug) circle(ROIcanvas, top, 3, cv::Scalar(0, 69, 255), 1);
- if (debug) circle(ROIcanvas, top, 63, cv::Scalar(0, 169, 255), 1);
- if (debug) circle(ROIcanvas, bottom, 3, cv::Scalar(0, 69, 255), 1);
- if (debug) circle(ROIcanvas, bottom, 63, cv::Scalar(0, 169, 255), 1);
- if (debug) rectangle(ROIcanvas, ROI_tl, ROI_br, cv::Scalar(0, 0, 255), 1);
- rectangle(canvas, ROI_tl, ROI_br, cv::Scalar(0, 0, 255), 1);
- if (debug) printf("-------------------------------------****------ roiF top=【%d, %d】, bottom=【%d, %d】\n", top.x, top.y, bottom.x, bottom.y);
- if (debug) printf(" roiF midP=【%f, %f】\n", midP.x, midP.y);
- if (debug) imshow("ROI", ROIcanvas);
- if (debug) imshow("ROI_canvas", canvas);
- //ROIcanvas.copyTo(canvas);
-
- return result;
- }
调用main:
- //两弧线夹圆弧 返回三点+骨干点集
- int main/*TwoArcsClipTheArc*/() {
- bool flag;
- std::string filePath = "../../img/圆弧夹圆弧";
-
- string resPath = "/output";
- //string resPath = filePath + "./output";
-
-
- cv::Point tlP = cv::Point(500, 292);
- cv::Point brP = cv::Point(750, 677);
- //cv::Rect ROI = cv::Rect(0, 0, 0, 0);
- //cv::Rect ROI = cv::Rect(0, 0, src.cols, src.rows);
- //cv::Rect ROI = cv::Rect(tlP.x, tlP.y, brP.x - tlP.x, brP.y - tlP.y);
- //cv::Rect ROI = cv::Rect(539, 218, 113, 513);
- cv::Rect ROI = cv::Rect(546, 228, 101, 520);
- cv::Point top(90, 90);
- cv::Point bottom(90, 90);
- cv::Point2f midP(90, 90);
- int outMidY;
- cv::Mat canvas;
- PTank_imgProcess m_ImageProcessing;
- ofstream ofs("log.txt", ios::out);
- if (ofs)
- {
- ofs.clear();
- ofs << "日志启动" << endl;
- }
- std::vector<cv::Point> allPntList;
- vector<string> path_name;
- bool arcTop_right = true;
-
- bool getROI = true;
- bool lianxu = false; //循环测试
-
- if (!lianxu)
- {
- string name = cv::format("\\Image_20240702114054217.png");
- //string name = cv::format("\\Image_20240702170558613.png");//斜
- //string name = cv::format("\\Image_20240702170644641.png");//斜
- string path = filePath + name;
- //string path = filePath + cv::format("\\ImgD_2023_08_17_15_06_45_412_639_188_125_569_Src.png");
- cv::Mat src = cv::imread(path);
- src.copyTo(canvas);
- cv::namedWindow("main_OriginalIMG", cv::NORMCONV_FILTER);
- cvSetMouseCallback("main_OriginalIMG", on_mouse_singleClick, 0);
- cv::imshow("main_OriginalIMG", src);
-
- //cv::Rect ROI = cv::Rect(0, 0, src.cols, src.rows);
- //cv::Rect ROI = cv::Rect(tlP.x, tlP.y, brP.x - tlP.x, brP.y - tlP.y);
- if (getROI) ROI = getROIFromString(name);
-
-
- bool flag = m_ImageProcessing.twoArcsClipTheArc_ROI(src, ROI, top, bottom, midP, allPntList, canvas, arcTop_right, true);
-
- cout << "\nmain ==== flag " << flag << endl;
- if (flag) {
- cout << "top = " << top.x << " " << top.y << endl;
- cout << "bottom = " << bottom.x << " " << bottom.y << endl;
- cout << "midP = " << midP.x << " " << midP.y << endl;
- }
- canvas.copyTo(src);
- //cout << "\nmain ==== i " << endl;
- circle(canvas, top, 63, cv::Scalar(0, 69, 255), 1);
- circle(canvas, bottom, 63, cv::Scalar(0, 69, 255), 1);
- cv::putText(src, to_string(flag), cv::Point(src.cols / 2 - 20, src.rows / 2 - 65), cv::FONT_HERSHEY_COMPLEX, 1.75, cv::Scalar(255, 135, 160), 3);
- cv::namedWindow("main-结果图src", cv::RECURS_FILTER);
- cvSetMouseCallback("main-结果图src", on_mouse_singleClick, 0);
- cv::imshow("main-结果图src", src);
- cv::namedWindow("main-canvas", cv::RECURS_FILTER);
- cvSetMouseCallback("main-canvas", on_mouse_singleClick, 0);
- cv::imshow("main-canvas", canvas);
- }
- else
- {
- vector<string> path_name;
- getAllFiles(filePath, path_name);
- cout << "path_name.size()=" << path_name.size() << endl;
-
- int number = 1;
- for (auto i : path_name)
- {
- //cout << i.size() << endl;
- if (i.size() == 7) continue;
- if (i.find(".log") != std::string::npos) continue;
- if (i.find(".txt") != std::string::npos) continue;
- if (i.find("_result") != std::string::npos) continue;
- if (i.find("png") == std::string::npos && i.find("bmp") == std::string::npos && i.find("jpg") == std::string::npos) continue;
- std::string path11 = filePath + "\\" + i;
- cv::Mat src = cv::imread(path11);
- //cv::Mat src = cv::imread(filePath + "\\" + i);
- cout << endl << "number【" << number << "】src path=" << i << " ;" << endl;
- src.copyTo(canvas);
- cv::imshow("main_OriginalIMG", src);
-
- //将结果图写入文件方便查看结果
- int len = filePath.length();
- //i = i.substr(i.find_last_of('\\') + 1, len);
- cout << "i=" << i << ", path11=" << path11 << endl;
- int time_start = clock();
- int time_end = clock();
-
- cv::Rect ROI = cv::Rect(0, 0, src.cols, src.rows);
- //cv::Rect ROI = cv::Rect(tlP.x, tlP.y, brP.x - tlP.x, brP.y - tlP.y);
- if (getROI) ROI = getROIFromString(i);
-
-
- bool flag = m_ImageProcessing.twoArcsClipTheArc_ROI(src, ROI, top, bottom, midP, allPntList, canvas, arcTop_right, false);
-
-
- time_end = clock();
- printf("\n耗时 %d ms \n", time_end - time_start);
- cout << "\nmain ==== flag " << flag << endl;
- if (flag) {
- cout << "top = " << top.x << " " << top.y << endl;
- cout << "bottom = " << bottom.x << " " << bottom.y << endl;
- }
- canvas.copyTo(src);
- cv::putText(src, to_string(flag), cv::Point(src.cols / 2 - 20, src.rows / 2 - 65), cv::FONT_HERSHEY_COMPLEX, 1.75, cv::Scalar(255, 135, 160), 3);
- cv::imshow("main-结果图src", src);
- cv::imshow("main-canvas", canvas);
-
-
- //将结果图写入文件方便查看结果
- char* filePath_ = new char[len + 1];
- strcpy(filePath_, filePath.c_str());
-
- len = filePath.length();
- char* resPath_ = new char[len + 1];
- strcpy(resPath_, resPath.c_str());
- //i.erase(0, strlen(filePath_) - strlen(resPath_) - 2);
-
- string out = filePath + resPath;
- cout << "\nmain ==== i " << i << endl;
- out.append("\\").append(i);
-
- cout << "number【" << number << "】res path=" << out << endl;
- cv::imwrite(out, src);
- number++;
-
- cout << "path_name.size() = " << path_name.size() << endl;
- cout << "*********************************************************************************************************************" << endl;
- cv::waitKey(10);
- }
- cout << "循环结束!!! main " << endl;
- }
-
- ofs.close();
- cv::waitKey(0);
- system("Pause");
- return 0;
- }
左右翻转变回来后必须要x-1,不然会与原来基于原图上的坐标对应不上。
- /*
- //D型管的两直线夹圆弧
- //周六新策略:两边直线中间圆弧,激光平行于主管 (__O__两端直线中间半圆弧找圆弧的两端拐点)---圆轨迹
- cv::Mat img, 原图
- cv::Rect ROI, 可以让右边的干扰直反光落进去,上下不用截,左右可适当截小一下减少识别时的计算时间
- int outMidY,因y偏差过大时返回的两点无效,则返回圆弧区域的中心y
- cv::Point& midP, outMidY对应的圆弧上的骨干点(midP为(0,0)时,该值无效)
- std::vector<cv::Point>& linearPnt:直线部分非弧线的点集
- cv::Point& top, 输出焊点(图像上位于较上方的点)
- cv::Point& bottom, 输出焊点(图像上位于较下方的点)
- cv::Mat &canvas,效果图可视化
- int midyTolerant = 2;//outMidY的容差范围
- bool arcTop_right = true;//圆弧顶点是否朝右的标志量,默认为true(true为朝右,false为朝左)
- */
- bool LaserParallelToTheMainD(cv::Mat imgOriginal, int &outMidY, cv::Point2f& midP, std::vector<cv::Point>& linearPntT, std::vector<cv::Point>& linearPntB, cv::Point& top, cv::Point& bottom, cv::Mat &canvas, int midyTolerant, bool debug = false);
- bool LaserParallelToTheMainD_ROI(cv::Mat img, cv::Rect ROI, int &outMidY, cv::Point2f& midP, std::vector<cv::Point>& linearPntT, std::vector<cv::Point>& linearPntB, cv::Point& top, cv::Point& bottom, cv::Mat &canvas, int midyTolerant = 2, bool arcTop_right = true, bool debug = false);
- bool ImageProcessing::LaserParallelToTheMainD_ROI(cv::Mat img, cv::Rect ROI, int &outMidY, cv::Point2f& midP, std::vector<cv::Point>& linearPntT, std::vector<cv::Point>& linearPntB, cv::Point & top, cv::Point & bottom, cv::Mat & canvas, int midyTolerant, bool arcTop_right, bool debug)
- {
- int endRes = 0;
- bool result = false;
- img.copyTo(canvas);
- top = cv::Point(0, 0);
- bottom = cv::Point(0, 0);
- midP = cv::Point2f(0, 0);
- linearPntT.clear();
- linearPntB.clear();
- outMidY = 0;
-
- cv::Mat imgOriginal;
- bool ROI_flag;//是否有给信息区
- cv::Point ROI_tl = cv::Point2i(ROI.x, ROI.y);
- cv::Point ROI_br = cv::Point2i(ROI.x + ROI.width, ROI.y + ROI.height);
- if (ROI_tl == cv::Point(0, 0) && ROI_br == cv::Point(0, 0) || ROI.width == 0 || ROI.height == 0)
- {
- img.copyTo(imgOriginal);
- ROI_flag = false;
- }
- else
- {
- if (ROI_tl.x > ROI_br.x || ROI_tl.y > ROI_br.y)//信息区两点疑似传反
- {
- printf("信息区两点疑似传反!");
- return false;
- }
- if (ROI_tl.x < 0 || ROI_br.x > img.cols || ROI_tl.y < 0 || ROI_br.y > img.rows)//信息区的框选超出图像范围
- {
- printf("信息区的框选超出图像范围!");
- return false;
- }
- if (abs(ROI_tl.x - ROI_br.x) > img.cols || abs(ROI_tl.y - ROI_br.y) > img.rows)//信息区大小超出图像大小
- {
- printf("信息区大小超出图像大小!");
- return false;
- }
-
- //此时不合法的ROI都已提前返回false
-
- cv::Rect roi(ROI_tl.x, ROI_tl.y, ROI_br.x - ROI_tl.x, ROI_br.y - ROI_tl.y);
- imgOriginal = img(roi); //裁剪出的ROI区域放于imgOriginal
- ROI_flag = true;
- }
-
- if (arcTop_right) {//圆弧顶点朝右的情况
- result = LaserParallelToTheMainD(imgOriginal, outMidY, midP, linearPntT, linearPntB, top, bottom, canvas, midyTolerant, debug);//调用识别算法
- }
- else {//圆弧顶点朝左的情况
- cv::Mat flipMat;
- cv::flip(imgOriginal, flipMat, 1); // 左右翻转 y对称
- if (debug) imshow("图像左右翻转", flipMat);
- result = LaserParallelToTheMainD(flipMat, outMidY, midP, linearPntT, linearPntB, top, bottom, canvas, midyTolerant, debug);//调用识别算法
- if (result) {
- top.x = flipMat.cols - top.x - 1;
- bottom.x = flipMat.cols - bottom.x - 1;
- for (int i = 0; i < linearPntT.size(); i++) {
- linearPntT.at(i).x = flipMat.cols - linearPntT.at(i).x - 1;
- }
- for (int i = 0; i < linearPntB.size(); i++) {
- linearPntB.at(i).x = flipMat.cols - linearPntB.at(i).x - 1;
- }
- if (midP != cv::Point2f(0, 0)) midP.x = flipMat.cols - midP.x - 1;
- }
- }
-
-
- if (debug) printf("-------------------------------------****------ roiF top=【%d, %d】, bottom=【%d, %d】\n", top.x, top.y, bottom.x, bottom.y);
- if (debug) printf(" roiF midP=【%f, %f】\n", midP.x, midP.y);
- //img.copyTo(canvas);
-
-
- x值和y值补上ROI左上点x和y
- //if (ROI_flag) {
- // if (Corner != cv::Point(0, 0))
- // {
- // Corner.x += ROI_tl.x;
- // Corner.y += ROI_tl.y;
- // }
- //}
-
- img.copyTo(canvas);//调试时注释掉
- if (result)
- {
- endRes = 1;
- top += ROI_tl;
- bottom += ROI_tl;
- if (midP != cv::Point2f(0, 0)) {
- midP.x = midP.x + ROI_tl.x;
- midP.y = midP.y + ROI_tl.y;
- }
- cv::line(canvas, midP, cv::Point2f(5, midP.y), cv::Scalar(55, 195, 40), 1);
- cv::line(canvas, cv::Point2f(midP.x, midP.y - 5), cv::Point2f(midP.x, midP.y + 5), cv::Scalar(55, 195, 40), 1);
- for (int i = 0; i < linearPntT.size(); i++) {
- linearPntT.at(i) += ROI_tl;
- }
- for (int i = 0; i < linearPntB.size(); i++) {
- linearPntB.at(i) += ROI_tl;
- }
- for (int i = 0; i < linearPntT.size(); i++) {
- cv::Point curPoint = linearPntT.at(i);
- cv::line(canvas, curPoint, cv::Point(curPoint.x - 5, curPoint.y), cv::Scalar(55, 195, 40), 1);
- }
- for (int i = 0; i < linearPntB.size(); i++) {
- cv::Point curPoint = linearPntB.at(i);
- cv::line(canvas, curPoint, cv::Point(curPoint.x - 5, curPoint.y), cv::Scalar(55, 195, 40), 1);
- }
- cv::putText(canvas, "true", { cv::Point(50, 50) }, cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(255, 255, 255), 1);
- circle(canvas, top, 3, cv::Scalar(0, 69, 255), 1);
- circle(canvas, top, 63, cv::Scalar(0, 169, 255), 1);
- circle(canvas, bottom, 3, cv::Scalar(0, 69, 255), 1);
- circle(canvas, bottom, 43, cv::Scalar(255, 169, 0), 1);
- }
- else
- {
- cv::putText(canvas, "false", { cv::Point(50, 50) }, cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(255, 255, 255), 1);
- }
-
-
- cv::Mat ROIcanvas;
- img.copyTo(ROIcanvas);
- if (debug) circle(ROIcanvas, top, 3, cv::Scalar(0, 69, 255), 1);
- if (debug) circle(ROIcanvas, top, 63, cv::Scalar(0, 169, 255), 1);
- if (debug) circle(ROIcanvas, bottom, 3, cv::Scalar(0, 69, 255), 1);
- if (debug) circle(ROIcanvas, bottom, 63, cv::Scalar(0, 169, 255), 1);
- if (debug) rectangle(ROIcanvas, ROI_tl, ROI_br, cv::Scalar(0, 0, 255), 1);
- rectangle(canvas, ROI_tl, ROI_br, cv::Scalar(0, 0, 255), 1);
- if (debug) printf("-------------------------------------****------ roiF top=【%d, %d】, bottom=【%d, %d】\n", top.x, top.y, bottom.x, bottom.y);
- if (debug) printf(" roiF midP=【%f, %f】\n", midP.x, midP.y);
- if (debug) imshow("ROI", ROIcanvas);
- if (debug) imshow("ROI_canvas", canvas);
- //ROIcanvas.copyTo(canvas);
-
- return result;
- }
调用main:
- //CXL 两边直线中间圆弧,激光平行于主管 DDDDDDDDDDDDDDDDD 圆轨迹 增加直线部分点集 的重载
- int main() {
- bool flag;
- std::string filePath = "../../../../Log08141641/TestImg/src";
-
-
- string resPath = "/output";
- //string resPath = filePath + "./output";
-
-
- cv::Point tlP = cv::Point(500, 292);
- cv::Point brP = cv::Point(750, 677);
- //cv::Rect ROI = cv::Rect(0, 0, 0, 0);
- //cv::Rect ROI = cv::Rect(0, 0, src.cols, src.rows);
- //cv::Rect ROI = cv::Rect(tlP.x, tlP.y, brP.x - tlP.x, brP.y - tlP.y);
- //cv::Rect ROI = cv::Rect(539, 218, 113, 513);
- cv::Point top(90, 90);
- cv::Point bottom(90, 90);
- cv::Point2f midP(90, 90);
- int outMidY;
- cv::Mat canvas;
- ImageProcessing m_ImageProcessing;
- ofstream ofs("log.txt", ios::out);
- if (ofs)
- {
- ofs.clear();
- ofs << "日志启动" << endl;
- }
- std::vector<cv::Point> linearPntT;
- std::vector<cv::Point> linearPntB;
- vector<string> path_name;
- bool arcTop_right = !true;
- int midyTolerant = 4;
-
- bool getROI = true;
- bool lianxu = false; //循环测试
-
- if (!lianxu)
- {
- string name = cv::format("\\ImgD_2024_06_04_09_14_48_111_565_82_86_851_Src.png");
- string path = filePath + name;
- //string path = filePath + cv::format("\\ImgD_2023_08_17_15_06_45_412_639_188_125_569_Src.png");
- cv::Mat src = cv::imread(path);
- src.copyTo(canvas);
- cv::namedWindow("main_OriginalIMG", cv::NORMCONV_FILTER);
- cvSetMouseCallback("main_OriginalIMG", on_mouse_singleClick, 0);
- cv::imshow("main_OriginalIMG", src);
-
- //cv::Rect ROI = cv::Rect(0, 0, src.cols, src.rows);
- //cv::Rect ROI = cv::Rect(tlP.x, tlP.y, brP.x - tlP.x, brP.y - tlP.y);
- if (getROI) ROI = getROIFromString(name);
-
- //trueX=outY;
- //trueY=oriSrc.rows-outX;
- //circle(src, cv::Point(622, 424), 5, cv::Scalar(255, 255, 255), -1);
- //cv::Mat flipMat;
- //cv::flip(src, flipMat, 1);
- //cv::Point q = cv::Point(flipMat.cols - 622 - 1, 424)/* - cv::Point(546, 228)*/;
- //circle(flipMat, q, 3, cv::Scalar(0, 0, 0), -1);
- //cv::imshow("flipMat", flipMat);
- //cv::waitKey();
-
- bool flag = m_ImageProcessing.LaserParallelToTheMainD_ROI(src, ROI, outMidY, midP, linearPntT, linearPntB, top, bottom, canvas, midyTolerant, arcTop_right, true);
-
- cout << "\nmain ==== flag " << flag << endl;
- if (flag) {
- cout << "top = " << top.x << " " << top.y << endl;
- cout << "bottom = " << bottom.x << " " << bottom.y << endl;
- }
- canvas.copyTo(src);
- //cout << "\nmain ==== i " << endl;
- circle(canvas, top, 63, cv::Scalar(0, 69, 255), 1);
- circle(canvas, bottom, 63, cv::Scalar(0, 69, 255), 1);
- cv::putText(src, to_string(flag), cv::Point(src.cols / 2 - 20, src.rows / 2 - 65), cv::FONT_HERSHEY_COMPLEX, 1.75, cv::Scalar(255, 135, 160), 3);
- cv::namedWindow("main-结果图src", cv::RECURS_FILTER);
- cvSetMouseCallback("main-结果图src", on_mouse_singleClick, 0);
- cv::imshow("main-结果图src", src);
- cv::namedWindow("main-canvas", cv::RECURS_FILTER);
- cvSetMouseCallback("main-canvas", on_mouse_singleClick, 0);
- cv::imshow("main-canvas", canvas);
- }
- else
- {
- vector<string> path_name;
- getAllFiles(filePath, path_name);
- cout << "path_name.size()=" << path_name.size() << endl;
-
- int number = 1;
- for (auto i : path_name)
- {
- //cout << i.size() << endl;
- if (i.size() == 7) continue;
- if (i.find(".log") != std::string::npos) continue;
- if (i.find(".txt") != std::string::npos) continue;
- if (i.find("_result") != std::string::npos) continue;
- if (i.find("png") == std::string::npos && i.find("bmp") == std::string::npos && i.find("jpg") == std::string::npos) continue;
- std::string path11 = filePath + "\\" + i;
- cv::Mat src = cv::imread(path11);
- //cv::Mat src = cv::imread(filePath + "\\" + i);
- cout << endl << "number【" << number << "】src path=" << i << " ;" << endl;
- src.copyTo(canvas);
- cv::imshow("main_OriginalIMG", src);
-
- //将结果图写入文件方便查看结果
- int len = filePath.length();
- //i = i.substr(i.find_last_of('\\') + 1, len);
- cout << "i=" << i << ", path11=" << path11 << endl;
- int time_start = clock();
- int time_end = clock();
-
- cv::Rect ROI = cv::Rect(0, 0, src.cols, src.rows);
- //cv::Rect ROI = cv::Rect(tlP.x, tlP.y, brP.x - tlP.x, brP.y - tlP.y);
- if (getROI) ROI = getROIFromString(i);
-
-
- bool flag = m_ImageProcessing.LaserParallelToTheMainD_ROI(src, ROI, outMidY, midP, linearPntT, linearPntB, top, bottom, canvas, midyTolerant, arcTop_right, false);
-
-
- time_end = clock();
- printf("\n耗时 %d ms \n", time_end - time_start);
- cout << "\nmain ==== flag " << flag << endl;
- if (flag) {
- cout << "top = " << top.x << " " << top.y << endl;
- cout << "bottom = " << bottom.x << " " << bottom.y << endl;
- }
- canvas.copyTo(src);
- cv::putText(src, to_string(flag), cv::Point(src.cols / 2 - 20, src.rows / 2 - 65), cv::FONT_HERSHEY_COMPLEX, 1.75, cv::Scalar(255, 135, 160), 3);
- cv::imshow("main-结果图src", src);
- cv::imshow("main-canvas", canvas);
-
-
- //将结果图写入文件方便查看结果
- char* filePath_ = new char[len + 1];
- strcpy(filePath_, filePath.c_str());
-
- len = filePath.length();
- char* resPath_ = new char[len + 1];
- strcpy(resPath_, resPath.c_str());
- //i.erase(0, strlen(filePath_) - strlen(resPath_) - 2);
-
- string out = filePath + resPath;
- cout << "\nmain ==== i " << i << endl;
- out.append("\\").append(i);
-
- cout << "number【" << number << "】res path=" << out << endl;
- cv::imwrite(out, src);
- number++;
-
- cout << "path_name.size() = " << path_name.size() << endl;
- cout << "*********************************************************************************************************************" << endl;
- cv::waitKey(10);
- }
- cout << "循环结束!!! main " << endl;
- }
-
- ofs.close();
- cv::waitKey(0);
- system("Pause");
- return 0;
- }
- /*
- //矩形位置 返回四点+骨干点集
- cv::Mat img, 原图
- cv::Rect ROI,
- cv::Point & p1, 图像较上方的主管底部点
- cv::Point & p2, 图像较上方的矩形顶部边缘点
- cv::Point & p3, 图像较下方的主管底部点
- cv::Point & p4,图像较下方的矩形顶部边缘点
- std::vector<cv::Point>& allPntList:直线部分非弧线的点集
- cv::Mat &canvas,效果图可视化
- */
- bool rectangle4Pnt(cv::Mat imgOriginal, cv::Point & p1, cv::Point& p2, cv::Point & p3, cv::Point& p4, std::vector<cv::Point>& allPntList, cv::Mat &canvas, bool debug = false);
- bool rectangle4Pnt_ROI(cv::Mat img, cv::Rect ROI, cv::Point & p1, cv::Point& p2, cv::Point & p3, cv::Point& p4, std::vector<cv::Point>& allPntList, cv::Mat &canvas, bool debug = false);
- bool PTank_imgProcess::rectangle4Pnt_ROI(cv::Mat img, cv::Rect ROI, cv::Point & p1, cv::Point& p2, cv::Point & p3, cv::Point& p4, std::vector<cv::Point>& allPntList, cv::Mat & canvas, bool debug)
- {
- int endRes = 0;
- bool result = false;
- img.copyTo(canvas);
- p1 = cv::Point(0, 0);
- p2 = cv::Point(0, 0);
- p3 = cv::Point(0, 0);
- p4 = cv::Point(0, 0);
- allPntList.clear();
-
- cv::Mat imgOriginal;
- bool ROI_flag;//是否有给信息区
- cv::Point ROI_tl = cv::Point2i(ROI.x, ROI.y);
- cv::Point ROI_br = cv::Point2i(ROI.x + ROI.width, ROI.y + ROI.height);
- if (ROI_tl == cv::Point(0, 0) && ROI_br == cv::Point(0, 0) || ROI.width == 0 || ROI.height == 0)
- {
- img.copyTo(imgOriginal);
- ROI_flag = false;
- }
- else
- {
- if (ROI_tl.x > ROI_br.x || ROI_tl.y > ROI_br.y)//信息区两点疑似传反
- {
- printf("信息区两点疑似传反!");
- return false;
- }
- if (ROI_tl.x < 0 || ROI_br.x > img.cols || ROI_tl.y < 0 || ROI_br.y > img.rows)//信息区的框选超出图像范围
- {
- printf("信息区的框选超出图像范围!");
- return false;
- }
- if (abs(ROI_tl.x - ROI_br.x) > img.cols || abs(ROI_tl.y - ROI_br.y) > img.rows)//信息区大小超出图像大小
- {
- printf("信息区大小超出图像大小!");
- return false;
- }
-
- //此时不合法的ROI都已提前返回false
-
- cv::Rect roi(ROI_tl.x, ROI_tl.y, ROI_br.x - ROI_tl.x, ROI_br.y - ROI_tl.y);
- imgOriginal = img(roi); //裁剪出的ROI区域放于imgOriginal
- ROI_flag = true;
- }
-
- result = rectangle4Pnt(imgOriginal, p1, p2, p3, p4, allPntList, canvas, debug);//调用识别算法
-
-
- if (debug) printf("-------------------------------------****------ roiF p1=【%d, %d】, p2=【%d, %d】\n", p1.x, p1.y, p2.x, p2.y);
- if (debug) printf("-------------------------------------****------ roiF p3=【%d, %d】, p4=【%d, %d】\n", p3.x, p3.y, p4.x, p4.y);
- //img.copyTo(canvas);
-
- img.copyTo(canvas);//调试时注释掉
- if (result)
- {
- endRes = 1;
- p1 += ROI_tl;
- p2 += ROI_tl;
- p3 += ROI_tl;
- p4 += ROI_tl;
- for (int i = 0; i < allPntList.size(); i++) {
- allPntList.at(i) += ROI_tl;
- }
- int w = 5;
- for (int i = 0; i < allPntList.size(); i++) {
- cv::Point curPoint = allPntList.at(i);
- cv::line(canvas, curPoint, cv::Point(curPoint.x - w, curPoint.y), cv::Scalar(55, 195, 40), 1);
- }
- cv::putText(canvas, "true", { cv::Point(50, 50) }, cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(255, 255, 255), 1);
- circle(canvas, p1, 3, cv::Scalar(0, 69, 255), 1);
- circle(canvas, p1, 63, cv::Scalar(0, 169, 255), 1);
- circle(canvas, p2, 3, cv::Scalar(0, 69, 255), 1);
- circle(canvas, p2, 43, cv::Scalar(255, 169, 0), 1);
-
- circle(canvas, p3, 3, cv::Scalar(0, 69, 255), 1);
- circle(canvas, p3, 63, cv::Scalar(0, 169, 255), 1);
- circle(canvas, p4, 3, cv::Scalar(0, 69, 255), 1);
- circle(canvas, p4, 43, cv::Scalar(255, 169, 0), 1);
- }
- else
- {
- cv::putText(canvas, "false", { cv::Point(50, 50) }, cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(255, 255, 255), 1);
- }
-
-
- cv::Mat ROIcanvas;
- img.copyTo(ROIcanvas);
- if (debug) circle(ROIcanvas, p1, 3, cv::Scalar(0, 69, 255), 1);
- if (debug) circle(ROIcanvas, p1, 63, cv::Scalar(0, 169, 255), 1);
- if (debug) circle(ROIcanvas, p2, 3, cv::Scalar(0, 69, 255), 1);
- if (debug) circle(ROIcanvas, p2, 63, cv::Scalar(0, 169, 255), 1);
-
- if (debug) circle(ROIcanvas, p3, 3, cv::Scalar(0, 69, 255), 1);
- if (debug) circle(ROIcanvas, p3, 63, cv::Scalar(0, 169, 255), 1);
- if (debug) circle(ROIcanvas, p4, 3, cv::Scalar(0, 69, 255), 1);
- if (debug) circle(ROIcanvas, p4, 63, cv::Scalar(0, 169, 255), 1);
- if (debug) rectangle(ROIcanvas, ROI_tl, ROI_br, cv::Scalar(0, 0, 255), 1);
- rectangle(canvas, ROI_tl, ROI_br, cv::Scalar(0, 0, 255), 1);
- if (debug) printf("---------------****------ roiF p1=【%d, %d】, p2=【%d, %d】\n", p1.x, p1.y, p2.x, p2.y);
- if (debug) printf("---------------****------ roiF p3=【%d, %d】, p4=【%d, %d】\n", p3.x, p3.y, p4.x, p4.y);
- if (debug) imshow("ROI", ROIcanvas);
- if (debug) imshow("ROI_canvas", canvas);
- //ROIcanvas.copyTo(canvas);
-
- return result;
- }
调用main:
- //矩形位置 返回四点+骨干点集
- int main/*Rectangle4Pnt_ROI*/() {
- bool flag;
- //std::string filePath = "../../../../Log08141641/TestImg/src";
- std::string filePath = "E://vsproject//压力罐\\img\\矩形";
-
-
- string resPath = "/output";
- //string resPath = filePath + "./output";
-
-
- cv::Point tlP = cv::Point(500, 292);
- cv::Point brP = cv::Point(750, 677);
- //cv::Rect ROI = cv::Rect(0, 0, 0, 0);
- //cv::Rect ROI = cv::Rect(0, 0, src.cols, src.rows);
- //cv::Rect ROI = cv::Rect(tlP.x, tlP.y, brP.x - tlP.x, brP.y - tlP.y);
- //cv::Rect ROI = cv::Rect(539, 218, 113, 513);
- cv::Point top(90, 90);
- cv::Point bottom(90, 90);
- cv::Point p3(90, 90);
- cv::Point p4(90, 90);
- int outMidY;
- cv::Mat canvas;
- PTank_imgProcess m_ImageProcessing;
- ofstream ofs("log.txt", ios::out);
- if (ofs)
- {
- ofs.clear();
- ofs << "日志启动" << endl;
- }
- std::vector<cv::Point> allPntList;
- vector<string> path_name;
-
-
- bool getROI = true;
- bool lianxu = false; //循环测试
-
- if (lianxu)
- {
- string name = cv::format("\\Image_20240627144521008.png");
- string path = filePath + name;
- cv::Mat src = cv::imread(path);
- src.copyTo(canvas);
- cv::namedWindow("main_OriginalIMG", cv::RECURS_FILTER);
- cvSetMouseCallback("main_OriginalIMG", on_mouse_singleClick, 0);
- cv::imshow("main_OriginalIMG", src);
-
- //cv::Rect ROI = cv::Rect(0, 0, src.cols, src.rows);
- cv::Rect ROI = cv::Rect(tlP.x, tlP.y, brP.x - tlP.x, brP.y - tlP.y);
- if (getROI) ROI = getROIFromString(name);
-
-
- bool flag = m_ImageProcessing.rectangle4Pnt_ROI(src, ROI, top, bottom, p3, p4, allPntList, canvas, true);
-
- cout << "\nmain ==== flag " << flag << endl;
- if (flag) {
- cout << "top = " << top.x << " " << top.y << endl;
- cout << "bottom = " << bottom.x << " " << bottom.y << endl;
- }
- canvas.copyTo(src);
- //cout << "\nmain ==== i " << endl;
- circle(canvas, top, 63, cv::Scalar(0, 69, 255), 1);
- circle(canvas, bottom, 63, cv::Scalar(0, 69, 255), 1);
- cv::putText(src, to_string(flag), cv::Point(src.cols / 2 - 20, src.rows / 2 - 65), cv::FONT_HERSHEY_COMPLEX, 1.75, cv::Scalar(255, 135, 160), 3);
- cv::namedWindow("main-结果图src", cv::RECURS_FILTER);
- cvSetMouseCallback("main-结果图src", on_mouse_singleClick, 0);
- cv::imshow("main-结果图src", src);
- cv::namedWindow("main-canvas", cv::RECURS_FILTER);
- cvSetMouseCallback("main-canvas", on_mouse_singleClick, 0);
- cv::imshow("main-canvas", canvas);
- }
- else
- {
- vector<string> path_name;
- getAllFiles(filePath, path_name);
- cout << "path_name.size()=" << path_name.size() << endl;
-
- int number = 1;
- for (auto i : path_name)
- {
- //cout << i.size() << endl;
- if (i.size() == 7) continue;
- if (i.find(".log") != std::string::npos) continue;
- if (i.find("png") == std::string::npos && i.find("bmp") == std::string::npos && i.find("jpg") == std::string::npos) continue;
- std::string path11 = filePath + "\\" + i;
- cv::Mat src = cv::imread(path11);
- //cv::Mat src = cv::imread(filePath + "\\" + i);
- cout << endl << "number【" << number << "】src path=" << i << " ;" << endl;
- src.copyTo(canvas);
- cv::imshow("main_OriginalIMG", src);
-
- //将结果图写入文件方便查看结果
- int len = filePath.length();
- //i = i.substr(i.find_last_of('\\') + 1, len);
- cout << "i=" << i << ", path11=" << path11 << endl;
- int time_start = clock();
- int time_end = clock();
-
- cv::Rect ROI = cv::Rect(0, 0, src.cols, src.rows);
- //cv::Rect ROI = cv::Rect(tlP.x, tlP.y, brP.x - tlP.x, brP.y - tlP.y);
- if (getROI) ROI = getROIFromString(i);
-
-
- bool flag = m_ImageProcessing.rectangle4Pnt_ROI(src, ROI, top, bottom, p3, p4, allPntList, canvas, false);
-
-
- time_end = clock();
- printf("\n耗时 %d ms \n", time_end - time_start);
- cout << "\nmain ==== flag " << flag << endl;
- if (flag) {
- cout << "top = " << top.x << " " << top.y << endl;
- cout << "bottom = " << bottom.x << " " << bottom.y << endl;
- }
- canvas.copyTo(src);
- cv::putText(src, to_string(flag), cv::Point(src.cols / 2 - 20, src.rows / 2 - 65), cv::FONT_HERSHEY_COMPLEX, 1.75, cv::Scalar(255, 135, 160), 3);
- cv::imshow("main-结果图src", src);
- cv::imshow("main-canvas", canvas);
-
-
- //将结果图写入文件方便查看结果
- char* filePath_ = new char[len + 1];
- strcpy(filePath_, filePath.c_str());
-
- len = filePath.length();
- char* resPath_ = new char[len + 1];
- strcpy(resPath_, resPath.c_str());
- //i.erase(0, strlen(filePath_) - strlen(resPath_) - 2);
-
- string out = filePath + resPath;
- cout << "\nmain ==== i " << i << endl;
- out.append("\\").append(i);
-
- cout << "number【" << number << "】res path=" << out << endl;
- cv::imwrite(out, src);
- number++;
-
- cout << "path_name.size() = " << path_name.size() << endl;
- cout << "*********************************************************************************************************************" << endl;
- cv::waitKey(10);
- }
- cout << "循环结束!!! main " << endl;
- }
-
- ofs.close();
- cv::waitKey(0);
- system("Pause");
- return 0;
- }
- /*
- //多层多道焊 圆管表面 & 四边形坡口拼接
- cv::Mat img, 原图
- cv::Point& top, 输出焊点(图像上位于较上方的点)
- cv::Point& bottom, 输出焊点(图像上位于较下方的点)
- std::vector<cv::Point>& groovePnt:坡口部分包括内侧面的点集
- cv::Point& valleyT, 位于焊道底部的焊点(图像上位于较上方的点)
- cv::Point& valleyB, 位于焊道底部的焊点(图像上位于较下方的点)
- std::vector<cv::Point>& valleyPnt,位于焊道底部的,焊道底部两点之间的点集
- cv::Mat &canvas,效果图可视化
- cv::Rect ROI,
- */
- bool multilayerMultichannel4(cv::Mat imgOriginal, cv::Point& top, cv::Point& bottom, std::vector<cv::Point>& groovePnt, cv::Point& valleyT, cv::Point& valleyB, std::vector<cv::Point>& valleyPnt, cv::Mat &canvas, bool debug = false);
- bool multilayerMultichannel4_ROI(cv::Mat img, cv::Point& top, cv::Point& bottom, std::vector<cv::Point>& groovePnt, cv::Point& valleyT, cv::Point& valleyB, std::vector<cv::Point>& valleyPnt, cv::Mat &canvas, cv::Rect ROI = cv::Rect(540, 540, 200, 200), bool debug = false);
- bool ImageProcess::multilayerMultichannel4_ROI(cv::Mat img, cv::Point & top, cv::Point & bottom, std::vector<cv::Point>& groovePnt, cv::Point & valleyT, cv::Point & valleyB, std::vector<cv::Point>& valleyPnt, cv::Mat & canvas, cv::Rect ROI, bool debug)
- {
- int endRes = 0;
- bool result = false;
- img.copyTo(canvas);
- top = cv::Point(0, 0);
- bottom = cv::Point(0, 0);
- groovePnt.clear();
- valleyT = cv::Point(0, 0);
- valleyB = cv::Point(0, 0);
- valleyPnt.clear();
-
- cv::Mat imgOriginal;
- bool ROI_flag;//是否有给信息区
- cv::Point ROI_tl = cv::Point2i(ROI.x, ROI.y);
- cv::Point ROI_br = cv::Point2i(ROI.x + ROI.width, ROI.y + ROI.height);
- if (ROI_tl == cv::Point(0, 0) && ROI_br == cv::Point(0, 0) || ROI.width == 0 || ROI.height == 0)
- {
- img.copyTo(imgOriginal);
- ROI_flag = false;
- }
- else
- {
- if (ROI_tl.x > ROI_br.x || ROI_tl.y > ROI_br.y)//信息区两点疑似传反
- {
- printf("信息区两点疑似传反!");
- return false;
- }
- if (ROI_tl.x < 0 || ROI_br.x > img.cols || ROI_tl.y < 0 || ROI_br.y > img.rows)//信息区的框选超出图像范围
- {
- printf("信息区的框选超出图像范围!");
- return false;
- }
- if (abs(ROI_tl.x - ROI_br.x) > img.cols || abs(ROI_tl.y - ROI_br.y) > img.rows)//信息区大小超出图像大小
- {
- printf("信息区大小超出图像大小!");
- return false;
- }
-
- //此时不合法的ROI都已提前返回false
-
- cv::Rect roi(ROI_tl.x, ROI_tl.y, ROI_br.x - ROI_tl.x, ROI_br.y - ROI_tl.y);
- imgOriginal = img(roi); //裁剪出的ROI区域放于imgOriginal
- ROI_flag = true;
- }
-
- result = multilayerMultichannel4(imgOriginal, top, bottom, groovePnt, valleyT, valleyB, valleyPnt, canvas, debug);//调用识别算法
-
-
- if (debug) printf("-------------------------------------****------ roiF top=【%d, %d】, bottom=【%d, %d】\n", top.x, top.y, bottom.x, bottom.y);
- if (debug) printf("----- roiF valleyT=【%d, %d】, valleyB=【%d, %d】\n", valleyT.x, valleyT.y, valleyB.x, valleyB.y);
- //img.copyTo(canvas);
-
-
- x值和y值补上ROI左上点x和y
- //if (ROI_flag) {
- // if (Corner != cv::Point(0, 0))
- // {
- // Corner.x += ROI_tl.x;
- // Corner.y += ROI_tl.y;
- // }
- //}
-
- img.copyTo(canvas);//调试时注释掉
-
- cv::Mat t1;
- canvas.convertTo(t1, -1, 1900 / 100.0, 100 - 100);//第一次线性变换100
- if (debug)cv::imshow("线性变换ROI", t1);
- t1.copyTo(canvas);
-
- if (result)
- {
- endRes = 1;
- top += ROI_tl;
- bottom += ROI_tl;
- valleyT += ROI_tl;
- valleyB += ROI_tl;
- for (int i = 0; i < groovePnt.size(); i++) {
- groovePnt.at(i) += ROI_tl;
- }
- for (int i = 0; i < valleyPnt.size(); i++) {
- valleyPnt.at(i) += ROI_tl;
- }
- int w = 9;
- for (int i = 0; i < groovePnt.size(); i++) {
- cv::Point curPoint = groovePnt.at(i);
- cv::line(canvas, curPoint, cv::Point(curPoint.x + w, curPoint.y), cv::Scalar(55, 195, 40), 1);
- }
- cv::putText(canvas, "true", { cv::Point(50, 50) }, cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(255, 255, 255), 1);
- circle(canvas, top, 3, cv::Scalar(0, 69, 255), 1);
- circle(canvas, top, 63, cv::Scalar(0, 169, 255), 1);
- circle(canvas, bottom, 3, cv::Scalar(0, 69, 255), 1);
- circle(canvas, bottom, 43, cv::Scalar(255, 169, 0), 1);
-
- circle(canvas, valleyT, 3, cv::Scalar(0, 69, 255), 1);
- circle(canvas, valleyT, 43, cv::Scalar(0, 169, 255), 1);
- circle(canvas, valleyB, 3, cv::Scalar(0, 69, 255), 1);
- circle(canvas, valleyB, 23, cv::Scalar(255, 169, 0), 1);
- for (int i = 0; i < valleyPnt.size(); i++) {
- cv::Point curPoint = valleyPnt.at(i);
- cv::line(canvas, curPoint, cv::Point(curPoint.x - w, curPoint.y), cv::Scalar(75, 155, 40), 1);
- }
- }
- else
- {
- cv::putText(canvas, "false", { cv::Point(50, 50) }, cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(255, 255, 255), 1);
- }
-
-
- cv::Mat ROIcanvas;
- img.copyTo(ROIcanvas);
- if (debug) circle(ROIcanvas, top, 3, cv::Scalar(0, 69, 255), 1);
- if (debug) circle(ROIcanvas, top, 63, cv::Scalar(0, 169, 255), 1);
- if (debug) circle(ROIcanvas, bottom, 3, cv::Scalar(0, 69, 255), 1);
- if (debug) circle(ROIcanvas, bottom, 63, cv::Scalar(0, 169, 255), 1);
- if (debug) rectangle(ROIcanvas, ROI_tl, ROI_br, cv::Scalar(0, 0, 255), 1);
- rectangle(canvas, ROI_tl, ROI_br, cv::Scalar(0, 0, 255), 1);
- if (debug) printf("-------------------------------------****------ roiF top=【%d, %d】, bottom=【%d, %d】\n", top.x, top.y, bottom.x, bottom.y);
- if (debug) printf("----- roiF valleyT=【%d, %d】, valleyB=【%d, %d】\n", valleyT.x, valleyT.y, valleyB.x, valleyB.y);
- if (debug) imshow("ROI", ROIcanvas);
- if (debug) imshow("ROI_canvas", canvas);
- //ROIcanvas.copyTo(canvas);
-
- return result;
- }
调用main:
- //multilayerMultichannel4_ROI 多层多道焊 圆管表面 & 四边形坡口拼接
- int main() {
- bool flag;
- //std::string filePath = "E:\\vsproject\\WeldingLine\\多层多道4";
- std::string filePath = "E:\\vsproject\\WeldingLine\\多层多道4\\TestImgAAA";
-
-
- std::string resPath = "/output";
- //string resPath = filePath + "./output";
-
-
- //cv::Point tlP = cv::Point(500, 40);
- //cv::Point brP = cv::Point(750, 777);
- cv::Point tlP = cv::Point(345, 108);
- cv::Point brP = cv::Point(859, 951);
- cv::Rect ROI = cv::Rect(0, 0, 0, 0);
- //cv::Rect ROI = cv::Rect(0, 0, src.cols, src.rows);
- //cv::Rect ROI = cv::Rect(tlP.x, tlP.y, brP.x - tlP.x, brP.y - tlP.y);
- //cv::Rect ROI = cv::Rect(544,208,107,545);
- //cv::Rect ROI = cv::Rect(639, 188, 125, 569);
- cv::Point top(90, 90);
- cv::Point bottom(90, 90);
- cv::Point valleyT(90, 90);
- cv::Point valleyB(90, 90);
- int outMidY;
- cv::Mat canvas;
- VisualInterface m_ImageProcessing;
- //ImageProcess m_ImageProcessing;
- std::vector<cv::Point> groovePnt;
- std::vector<cv::Point> valleyPnt;
- vector<string> path_name;
- bool arcTop_right = true;
- int midyTolerant = 4;
-
- bool getROI = !true;
- bool lianxu = false; //循环测试
-
- if (!lianxu)
- {
- string name = cv::format("\\SrcImg_2023_12_28_14_57_17_133_ROI_1132_999_401_126_src.png");
- //中间底部较高的情况
- string path = filePath + name;
- cv::Mat src = cv::imread(path);
- src.copyTo(canvas);
- cv::namedWindow("main_OriginalIMG", cv::NORMCONV_FILTER);
- cvSetMouseCallback("main_OriginalIMG", on_mouse_singleClick, 0);
- cv::imshow("main_OriginalIMG", src);
-
- cv::Rect ROI = cv::Rect(0, 0, src.cols, src.rows);
- //ROI = cv::Rect(400, 0, 400, src.rows);
- //cv::Rect ROI = cv::Rect(tlP.x, tlP.y, brP.x - tlP.x, brP.y - tlP.y);
- if (getROI) ROI = getROIFromString(name);
-
-
- bool flag = m_ImageProcessing.multilayerMultichannel4_ROI(src, top, bottom, groovePnt, valleyT, valleyB, valleyPnt, canvas, ROI, true);
-
- cout << "\nmain ==== flag " << flag << endl;
- if (flag) {
- cout << "top = " << top.x << " " << top.y << endl;
- cout << "bottom = " << bottom.x << " " << bottom.y << endl;
- }
- canvas.copyTo(src);
- //cout << "\nmain ==== i " << endl;
- circle(canvas, top, 63, cv::Scalar(0, 69, 255), 1);
- circle(canvas, bottom, 63, cv::Scalar(0, 69, 255), 1);
- cv::putText(src, to_string(flag), cv::Point(src.cols / 2 - 20, src.rows / 2 - 65), cv::FONT_HERSHEY_COMPLEX, 1.75, cv::Scalar(255, 135, 160), 3);
- cv::namedWindow("main-结果图src", cv::RECURS_FILTER);
- cvSetMouseCallback("main-结果图src", on_mouse_singleClick, 0);
- cv::imshow("main-结果图src", src);
- cv::namedWindow("main-canvas", cv::RECURS_FILTER);
- cvSetMouseCallback("main-canvas", on_mouse_singleClick, 0);
- cv::imshow("main-canvas", canvas);
- }
- else
- {
- vector<string> path_name;
- getAllFiles(filePath, path_name);
- cout << "path_name.size()=" << path_name.size() << endl;
-
- int number = 1;
- for (auto i : path_name)
- {
- //cout << i.size() << endl;
- if (i.size() == 7) continue;
- if (i.find(".log") != std::string::npos) continue;
- if (i.find(".txt") != std::string::npos) continue;
- if (i.find("_result") != std::string::npos) continue;
- if (i.find("png") == std::string::npos && i.find("bmp") == std::string::npos && i.find("jpg") == std::string::npos) continue;
- std::string path11 = filePath + "\\" + i;
- cv::Mat src = cv::imread(path11);
- //cv::Mat src = cv::imread(filePath + "\\" + i);
- cout << endl << "number【" << number << "】src path=" << i << " ;" << endl;
- src.copyTo(canvas);
- cv::imshow("main_OriginalIMG", src);
-
- //将结果图写入文件方便查看结果
- int len = filePath.length();
- //i = i.substr(i.find_last_of('\\') + 1, len);
- cout << "i=" << i << ", path11=" << path11 << endl;
- int time_start = clock();
- int time_end = clock();
-
- cv::Rect ROI = cv::Rect(0, 0, src.cols, src.rows);
- //ROI = cv::Rect(400, 0, 400, src.rows);
- cv::Rect ROI = cv::Rect(tlP.x, tlP.y, brP.x - tlP.x, brP.y - tlP.y);
- if (getROI) ROI = getROIFromString(i);
-
-
- bool flag = m_ImageProcessing.multilayerMultichannel4_ROI(src, top, bottom, groovePnt, valleyT, valleyB, valleyPnt, canvas, ROI, false);
-
-
- time_end = clock();
- printf("\n耗时 %d ms \n", time_end - time_start);
- cout << "\nmain ==== flag " << flag << endl;
- if (flag) {
- cout << "top = " << top.x << " " << top.y << endl;
- cout << "bottom = " << bottom.x << " " << bottom.y << endl;
- }
- canvas.copyTo(src);
- cv::putText(src, to_string(flag), cv::Point(src.cols / 2 - 20, src.rows / 2 - 65), cv::FONT_HERSHEY_COMPLEX, 1.75, cv::Scalar(255, 135, 160), 3);
- cv::imshow("main-结果图src", src);
- cv::imshow("main-canvas", canvas);
-
-
- //将结果图写入文件方便查看结果
- char* filePath_ = new char[len + 1];
- strcpy(filePath_, filePath.c_str());
-
- len = filePath.length();
- char* resPath_ = new char[len + 1];
- strcpy(resPath_, resPath.c_str());
- //i.erase(0, strlen(filePath_) - strlen(resPath_) - 2);
-
- string out = filePath + resPath;
- cout << "\nmain ==== i " << i << endl;
- out.append("\\").append(i);
-
- cout << "number【" << number << "】res path=" << out << endl;
- cv::imwrite(out, src);
- number++;
-
- cout << "path_name.size() = " << path_name.size() << endl;
- cout << "*********************************************************************************************************************" << endl;
- cv::waitKey(10);
- }
- cout << "循环结束!!! main " << endl;
- }
-
- cv::waitKey(0);
- system("Pause");
- return 0;
- }
- /*
- //两弧线夹悬空的圆弧 返回五点+骨干点集 定"L"型管相贯线水平用
- cv::Mat img, 原图
- cv::Rect ROI,
- cv::Point & p1, 图像较上方的主管底部点
- cv::Point & p2, 图像较上方的弧形激光边缘点
- cv::Point2f & midP, 圆弧中点
- cv::Point & p3, 图像较下方的弧形激光边缘点
- cv::Point & p4,图像较下方的主管底部点
- std::vector<cv::Point>& allPntList:直线部分非弧线的点集
- cv::Mat &canvas,效果图可视化
- */
- bool twoArcsClipTheHangingArc(cv::Mat imgOriginal, cv::Point & p1, cv::Point& p2, cv::Point2f& midP, cv::Point& p3, cv::Point& p4, std::vector<cv::Point>& allPntList, cv::Mat &canvas, bool debug = false);
- bool twoArcsClipTheHangingArc_ROI(cv::Mat img, cv::Rect ROI, cv::Point& p1, cv::Point& p2, cv::Point2f& midP, cv::Point& p3, cv::Point& p4, std::vector<cv::Point>& allPntList, cv::Mat &canvas, bool debug = false);
- bool PTank_imgProcess::twoArcsClipTheHangingArc_ROI(cv::Mat img, cv::Rect ROI, cv::Point & p1, cv::Point & p2, cv::Point2f & midP, cv::Point & p3, cv::Point & p4, std::vector<cv::Point>& allPntList, cv::Mat & canvas, bool debug)
- {
- int endRes = 0;
- bool result = false;
- img.copyTo(canvas);
- p1 = cv::Point(0, 0);
- p2 = cv::Point(0, 0);
- p3 = cv::Point(0, 0);
- p4 = cv::Point(0, 0);
- midP = cv::Point2f(0, 0);
- allPntList.clear();
-
- cv::Mat imgOriginal;
- bool ROI_flag;//是否有给信息区
- cv::Point ROI_tl = cv::Point2i(ROI.x, ROI.y);
- cv::Point ROI_br = cv::Point2i(ROI.x + ROI.width, ROI.y + ROI.height);
- if (ROI_tl == cv::Point(0, 0) && ROI_br == cv::Point(0, 0) || ROI.width == 0 || ROI.height == 0)
- {
- img.copyTo(imgOriginal);
- ROI_flag = false;
- }
- else
- {
- if (ROI_tl.x > ROI_br.x || ROI_tl.y > ROI_br.y)//信息区两点疑似传反
- {
- printf("信息区两点疑似传反!");
- return false;
- }
- if (ROI_tl.x < 0 || ROI_br.x > img.cols || ROI_tl.y < 0 || ROI_br.y > img.rows)//信息区的框选超出图像范围
- {
- printf("信息区的框选超出图像范围!");
- return false;
- }
- if (abs(ROI_tl.x - ROI_br.x) > img.cols || abs(ROI_tl.y - ROI_br.y) > img.rows)//信息区大小超出图像大小
- {
- printf("信息区大小超出图像大小!");
- return false;
- }
-
- //此时不合法的ROI都已提前返回false
-
- cv::Rect roi(ROI_tl.x, ROI_tl.y, ROI_br.x - ROI_tl.x, ROI_br.y - ROI_tl.y);
- imgOriginal = img(roi); //裁剪出的ROI区域放于imgOriginal
- ROI_flag = true;
- }
-
- result = twoArcsClipTheHangingArc(imgOriginal, p1, p2, midP, p3, p4, allPntList, canvas, debug);//调用识别算法
-
-
- if (debug) printf("-------------------------------------****------ roiF p1=【%d, %d】, p2=【%d, %d】\n", p1.x, p1.y, p2.x, p2.y);
- if (debug) printf("-------------------------------------****------ roiF p3=【%d, %d】, p4=【%d, %d】\n", p3.x, p3.y, p4.x, p4.y);
- if (debug) printf(" roiF midP=【%f, %f】\n", midP.x, midP.y);
- //img.copyTo(canvas);
-
- img.copyTo(canvas);//调试时注释掉
- if (result)
- {
- endRes = 1;
- p1 += ROI_tl;
- p2 += ROI_tl;
- p3 += ROI_tl;
- p4 += ROI_tl;
- midP += cv::Point2f(ROI_tl);
- for (int i = 0; i < allPntList.size(); i++) {
- allPntList.at(i) += ROI_tl;
- }
- int w = 5;
- for (int i = 0; i < allPntList.size(); i++) {
- cv::Point curPoint = allPntList.at(i);
- cv::line(canvas, curPoint, cv::Point(curPoint.x - w, curPoint.y), cv::Scalar(55, 195, 40), 1);
- }
- cv::putText(canvas, "true", { cv::Point(50, 50) }, cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(255, 255, 255), 1);
- circle(canvas, midP, 3, cv::Scalar(0, 69, 255), 1);
- circle(canvas, midP, 43, cv::Scalar(0, 169, 255), 1);
- cv::line(canvas, midP, cv::Point2f(5, midP.y), cv::Scalar(155, 195, 40), 1);
- cv::line(canvas, cv::Point2f(midP.x, midP.y - 5), cv::Point2f(midP.x, midP.y + 5), cv::Scalar(155, 195, 40), 1);
-
- circle(canvas, p1, 3, cv::Scalar(0, 69, 255), 1);
- circle(canvas, p1, 63, cv::Scalar(0, 169, 255), 1);
- circle(canvas, p2, 3, cv::Scalar(0, 69, 255), 1);
- circle(canvas, p2, 43, cv::Scalar(255, 169, 0), 1);
-
- circle(canvas, p3, 3, cv::Scalar(0, 69, 255), 1);
- circle(canvas, p3, 63, cv::Scalar(0, 169, 255), 1);
- circle(canvas, p4, 3, cv::Scalar(0, 69, 255), 1);
- circle(canvas, p4, 43, cv::Scalar(255, 169, 0), 1);
- }
- else
- {
- cv::putText(canvas, "false", { cv::Point(50, 50) }, cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(255, 255, 255), 1);
- }
-
-
- cv::Mat ROIcanvas;
- img.copyTo(ROIcanvas);
- if (debug) circle(ROIcanvas, p1, 3, cv::Scalar(0, 69, 255), 1);
- if (debug) circle(ROIcanvas, p1, 63, cv::Scalar(0, 169, 255), 1);
- if (debug) circle(ROIcanvas, p2, 3, cv::Scalar(0, 69, 255), 1);
- if (debug) circle(ROIcanvas, p2, 63, cv::Scalar(0, 169, 255), 1);
-
- if (debug) circle(ROIcanvas, p3, 3, cv::Scalar(0, 69, 255), 1);
- if (debug) circle(ROIcanvas, p3, 63, cv::Scalar(0, 169, 255), 1);
- if (debug) circle(ROIcanvas, p4, 3, cv::Scalar(0, 69, 255), 1);
- if (debug) circle(ROIcanvas, p4, 63, cv::Scalar(0, 169, 255), 1);
- if (debug) rectangle(ROIcanvas, ROI_tl, ROI_br, cv::Scalar(0, 0, 255), 1);
- rectangle(canvas, ROI_tl, ROI_br, cv::Scalar(0, 0, 255), 1);
- if (debug) printf("---------------****------ roiF p1=【%d, %d】, p2=【%d, %d】\n", p1.x, p1.y, p2.x, p2.y);
- if (debug) printf("---------------****------ roiF p3=【%d, %d】, p4=【%d, %d】\n", p3.x, p3.y, p4.x, p4.y);
- if (debug) printf("---------------****------ roiF midP=【%f, %f】\n", midP.x, midP.y);
- if (debug) imshow("ROI", ROIcanvas);
- if (debug) imshow("ROI_canvas", canvas);
- //ROIcanvas.copyTo(canvas);
-
- return result;
- }
调用main:
- //两弧线夹悬空的圆弧 返回五点+骨干点集 定"L"型管相贯线水平用
- int mainTwoArcsClipTheHangingArc() {
- bool flag;
- //std::string filePath = "../../../../Log08141641/TestImg/src";
- std::string filePath = "E://vsproject//压力罐\\img\\L型管定水平";
-
-
- string resPath = "/output";
- //string resPath = filePath + "./output";
-
-
- cv::Point tlP = cv::Point(500, 292);
- cv::Point brP = cv::Point(750, 677);
- //cv::Rect ROI = cv::Rect(0, 0, 0, 0);
- //cv::Rect ROI = cv::Rect(0, 0, src.cols, src.rows);
- //cv::Rect ROI = cv::Rect(tlP.x, tlP.y, brP.x - tlP.x, brP.y - tlP.y);
- //cv::Rect ROI = cv::Rect(539, 218, 113, 513);
- cv::Point top(90, 90);
- cv::Point bottom(90, 90);
- cv::Point p3(90, 90);
- cv::Point p4(90, 90);
- cv::Point2f midP(90, 90);
- int outMidY;
- cv::Mat canvas;
- PTank_imgProcess m_ImageProcessing;
- ofstream ofs("log.txt", ios::out);
- if (ofs)
- {
- ofs.clear();
- ofs << "日志启动" << endl;
- }
- std::vector<cv::Point> allPntList;
- std::vector<cv::Point> tPntList;
- std::vector<cv::Point> bPntList;
- std::vector<cv::Point> mPntList;
- vector<string> path_name;
-
-
- bool getROI = true;
- bool lianxu = false; //循环测试
-
- if (!lianxu)
- {
- string name = cv::format("\\Image_20240627151133378.png");
- string path = filePath + name;
- cv::Mat src = cv::imread(path);
- src.copyTo(canvas);
- cv::namedWindow("main_OriginalIMG", cv::RECURS_FILTER);
- cvSetMouseCallback("main_OriginalIMG", on_mouse_singleClick, 0);
- cv::imshow("main_OriginalIMG", src);
-
- //cv::Rect ROI = cv::Rect(0, 0, src.cols, src.rows);
- cv::Rect ROI = cv::Rect(tlP.x, tlP.y, brP.x - tlP.x, brP.y - tlP.y);
- if (getROI) ROI = getROIFromString(name);
-
-
- bool flag = m_ImageProcessing.twoArcsClipTheHangingArc_ROI(src, ROI, top, bottom, midP, p3, p4, allPntList, canvas, true);
- m_ImageProcessing.By4Pnt_SplitPLst_1to3(canvas, top, bottom, p3, p4, allPntList, tPntList, bPntList, mPntList, canvas, true);
-
- cout << "\nmain ==== flag " << flag << endl;
- if (flag) {
- cout << "top = " << top.x << " " << top.y << endl;
- cout << "bottom = " << bottom.x << " " << bottom.y << endl;
- cout << "midP = " << midP.x << " " << midP.y << endl;
- }
- canvas.copyTo(src);
- //cout << "\nmain ==== i " << endl;
- circle(canvas, top, 63, cv::Scalar(0, 69, 255), 1);
- circle(canvas, bottom, 63, cv::Scalar(0, 69, 255), 1);
- cv::putText(src, to_string(flag), cv::Point(src.cols / 2 - 20, src.rows / 2 - 65), cv::FONT_HERSHEY_COMPLEX, 1.75, cv::Scalar(255, 135, 160), 3);
- cv::namedWindow("main-结果图src", cv::RECURS_FILTER);
- cvSetMouseCallback("main-结果图src", on_mouse_singleClick, 0);
- cv::imshow("main-结果图src", src);
- cv::namedWindow("main-canvas", cv::RECURS_FILTER);
- cvSetMouseCallback("main-canvas", on_mouse_singleClick, 0);
- cv::imshow("main-canvas", canvas);
- }
- else
- {
- vector<string> path_name;
- getAllFiles(filePath, path_name);
- cout << "path_name.size()=" << path_name.size() << endl;
-
- int number = 1;
- for (auto i : path_name)
- {
- //cout << i.size() << endl;
- if (i.size() == 7) continue;
- if (i.find(".log") != std::string::npos) continue;
- if (i.find("png") == std::string::npos && i.find("bmp") == std::string::npos && i.find("jpg") == std::string::npos) continue;
- std::string path11 = filePath + "\\" + i;
- cv::Mat src = cv::imread(path11);
- //cv::Mat src = cv::imread(filePath + "\\" + i);
- cout << endl << "number【" << number << "】src path=" << i << " ;" << endl;
- src.copyTo(canvas);
- cv::imshow("main_OriginalIMG", src);
-
- //将结果图写入文件方便查看结果
- int len = filePath.length();
- //i = i.substr(i.find_last_of('\\') + 1, len);
- cout << "i=" << i << ", path11=" << path11 << endl;
- int time_start = clock();
- int time_end = clock();
-
- cv::Rect ROI = cv::Rect(0, 0, src.cols, src.rows);
- //cv::Rect ROI = cv::Rect(tlP.x, tlP.y, brP.x - tlP.x, brP.y - tlP.y);
- if (getROI) ROI = getROIFromString(i);
-
-
- bool flag = m_ImageProcessing.twoArcsClipTheHangingArc_ROI(src, ROI, top, bottom, midP, p3, p4, allPntList, canvas, false);
- m_ImageProcessing.By4Pnt_SplitPLst_1to3(canvas, top, bottom, p3, p4, allPntList, tPntList, bPntList, mPntList, canvas, false);
-
-
- time_end = clock();
- printf("\n耗时 %d ms \n", time_end - time_start);
- cout << "\nmain ==== flag " << flag << endl;
- if (flag) {
- cout << "top = " << top.x << " " << top.y << endl;
- cout << "bottom = " << bottom.x << " " << bottom.y << endl;
- cout << "midP = " << midP.x << " " << midP.y << endl;
- }
- canvas.copyTo(src);
- cv::putText(src, to_string(flag), cv::Point(src.cols / 2 - 20, src.rows / 2 - 65), cv::FONT_HERSHEY_COMPLEX, 1.75, cv::Scalar(255, 135, 160), 3);
- cv::imshow("main-结果图src", src);
- cv::imshow("main-canvas", canvas);
-
-
- //将结果图写入文件方便查看结果
- char* filePath_ = new char[len + 1];
- strcpy(filePath_, filePath.c_str());
-
- len = filePath.length();
- char* resPath_ = new char[len + 1];
- strcpy(resPath_, resPath.c_str());
- //i.erase(0, strlen(filePath_) - strlen(resPath_) - 2);
-
- string out = filePath + resPath;
- cout << "\nmain ==== i " << i << endl;
- out.append("\\").append(i);
-
- cout << "number【" << number << "】res path=" << out << endl;
- cv::imwrite(out, src);
- number++;
-
- cout << "path_name.size() = " << path_name.size() << endl;
- cout << "*********************************************************************************************************************" << endl;
- cv::waitKey(10);
- }
- cout << "循环结束!!! main " << endl;
- }
-
- ofs.close();
- cv::waitKey(0);
- system("Pause");
- return 0;
- }
- /*
- //泡泡
- cv::Mat img, 原图
- cv::Rect ROI,
- cv::Mat imgTemplate:模板图片(无泡泡的图)
- cv::Mat &canvas,效果图可视化
- */
- bool DetectingBubble(const cv::Mat imgOriginal, cv::Mat imgTemplate, std::vector<cv::Rect> &bubbles, cv::Mat &canvas, bool debug = false);
- bool DetectingBubble_ROI(cv::Mat img, cv::Mat imgTemplate, std::vector<cv::Rect> &bubbles, cv::Rect ROI, cv::Mat &canvas, bool debug = false);
- bool ImageProcessing::DetectingBubble_ROI(cv::Mat img, cv::Mat imgTemplate, std::vector<cv::Rect> &bubbles, cv::Rect ROI, cv::Mat & canvas, bool debug)
- {
- cout << __FUNCTION__ << endl;
- int endRes = 0;
- bool result = false;
- img.copyTo(canvas);
- bubbles.clear();
-
- cv::Mat imgOriginal;
- bool ROI_flag;//是否有给信息区
- cv::Point ROI_tl = cv::Point2i(ROI.x, ROI.y);
- cv::Point ROI_br = cv::Point2i(ROI.x + ROI.width, ROI.y + ROI.height);
- if (ROI_tl == cv::Point(0, 0) && ROI_br == cv::Point(0, 0) || ROI.width == 0 || ROI.height == 0)
- {
- img.copyTo(imgOriginal);
- ROI_flag = false;
- }
- else
- {
- if (ROI_tl.x > ROI_br.x || ROI_tl.y > ROI_br.y)//信息区两点疑似传反
- {
- printf("信息区两点疑似传反!");
- return false;
- }
- if (ROI_tl.x < 0 || ROI_br.x > img.cols || ROI_tl.y < 0 || ROI_br.y > img.rows)//信息区的框选超出图像范围
- {
- printf("信息区的框选超出图像范围!");
- return false;
- }
- if (abs(ROI_tl.x - ROI_br.x) > img.cols || abs(ROI_tl.y - ROI_br.y) > img.rows)//信息区大小超出图像大小
- {
- printf("信息区大小超出图像大小!");
- return false;
- }
-
- //此时不合法的ROI都已提前返回false
-
- cv::Rect roi(ROI_tl.x, ROI_tl.y, ROI_br.x - ROI_tl.x, ROI_br.y - ROI_tl.y);
- imgOriginal = img(roi); //裁剪出的ROI区域放于imgOriginal
- imgTemplate = imgTemplate(roi);
- ROI_flag = true;
- }
-
- result = DetectingBubble(imgOriginal, imgTemplate, bubbles, canvas, debug);//调用识别算法
-
-
- //if (debug) printf("-------------------------------------****------ roiF top=【%d, %d】, bottom=【%d, %d】\n", top.x, top.y, bottom.x, bottom.y);
-
-
- img.copyTo(canvas);//调试时注释掉
-
- cv::Mat t1;
- canvas.convertTo(t1, -1, 200 / 100.0, 0 + 55);
- //if (debug) cv::imshow("线性变换0", t1);
- t1.copyTo(canvas);
-
- if (result)
- {
- endRes = 1;
- cv::putText(canvas, "true", { cv::Point(50, 50) }, cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(255, 255, 255), 1);
- //for (int i = 0; i < bubbles.size(); i++) {
- // //bubbles.at(i).tl.x = bubbles.at(i).tl.x + ROI_tl.x;
- // //bubbles.at(i).tl.y = bubbles.at(i).tl.y + ROI_tl.y;
- // //bubbles.at(i).br.x = bubbles.at(i).br.x + ROI_tl.x;
- // //bubbles.at(i).br.y = bubbles.at(i).br.y + ROI_tl.y;
- // cv::Rect curBR = bubbles.at(i);
- // bubbles.at(i).x = bubbles.at(i).x + ROI_tl.x;
- // bubbles.at(i).y = bubbles.at(i).y + ROI_tl.y;
- // //curBR.tl.x = bubbles.at(i).tl.x + ROI_tl.x;
- // //curBR.tl.y = bubbles.at(i).tl.y + ROI_tl.y;
- // //curBR.br.x = bubbles.at(i).br.x + ROI_tl.x;
- // //curBR.br.y = bubbles.at(i).br.y + ROI_tl.y;
- //}
- for (int i = 0; i < bubbles.size(); i++) {//可视化
- bubbles.at(i).x = bubbles.at(i).x + ROI_tl.x;
- bubbles.at(i).y = bubbles.at(i).y + ROI_tl.y;
- cv::Rect curBR = bubbles.at(i);
- cv::rectangle(canvas, curBR.tl(), curBR.br(), cv::Scalar(0, 255, 0), 1);
- cv::putText(canvas, to_string(i), curBR.br(), cv::FONT_HERSHEY_COMPLEX, 0.45, cv::Scalar(55, 35, 160), 1);
- }
- }
- else
- {
- cv::putText(canvas, "false", { cv::Point(50, 50) }, cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(255, 255, 255), 1);
- }
-
- cv::Mat ROIcanvas;
- img.copyTo(ROIcanvas);
- if (debug) rectangle(ROIcanvas, ROI_tl, ROI_br, cv::Scalar(0, 0, 255), 1);
- rectangle(canvas, ROI_tl, ROI_br, cv::Scalar(0, 0, 255), 1);
- if (debug) imshow("ROI", ROIcanvas);
- if (debug) imshow("ROI_canvas", canvas);
- //ROIcanvas.copyTo(canvas);
-
- return result;
- }
调用main:
- //泡泡 OneSideSquare_ROI
- int main/*pp*/() {
- bool flag;
- std::string filePath = "../../../../泡泡/0708/6000";
- //std::string filePath = "../../../../泡泡/0708/20000";
-
-
- string resPath = "/output";
- //string resPath = filePath + "./output";
-
-
- cv::Point tlP = cv::Point(491, 50);
- cv::Point brP = cv::Point(1596, 760);
- tlP = cv::Point(1, 296);
- brP = cv::Point(1160, 2278);
- tlP = cv::Point(190, 0);
- brP = cv::Point(840, 1024);
- //cv::Rect ROI = cv::Rect(0, 0, 0, 0);
- //cv::Rect ROI = cv::Rect(0, 0, src.cols, src.rows);
- //cv::Rect ROI = cv::Rect(tlP.x, tlP.y, brP.x - tlP.x, brP.y - tlP.y);
- //cv::Rect ROI = cv::Rect(639, 188, 125, 569);
- cv::Point top(90, 90);
- cv::Point bottom(90, 90);
- cv::Point2f midP(90, 90);
- int outMidY;
- cv::Mat canvas;
- ImageProcessing m_ImageProcessing;
- ofstream ofs("log.txt", ios::out);
- if (ofs)
- {
- ofs.clear();
- ofs << "日志启动" << endl;
- }
- std::vector<cv::Rect> bubbles;//泡泡集合
- vector<Picture_set> img_buf;
- vector<string> path_name;
- //cv::Mat templ = cv::imread(filePath + cv::format("\\屏幕截图(13).png"));//模板图的灰度图
- cv::Mat templ = cv::imread(filePath + cv::format("\\Image_20240708175744959.png"));//6000
-
- bool getROI = !true;
- bool lianxu = false; //循环测试
-
- if (lianxu)
- {
- std::string name = cv::format("\\Image_20240708175747311.png");
- string path = filePath + name;
- cv::Mat src = cv::imread(path);
- src.copyTo(canvas);
- cv::namedWindow("main_OriginalIMG", cv::NORMCONV_FILTER);
- cvSetMouseCallback("main_OriginalIMG", on_mouse_singleClick, 0);
- cv::imshow("main_OriginalIMG", src);
- cv::imshow("templ", templ);
-
- //cv::Rect ROI = cv::Rect(0, 0, src.cols, src.rows);
- cv::Rect ROI = cv::Rect(tlP.x, tlP.y, brP.x - tlP.x, brP.y - tlP.y);
- if (getROI) {
- ROI = getROIFromString(name);
- }
- //cv::Mat imgCur = src - templ;
- imgCur = imgOriginal - imgTemplate;
- //if (1) cv::imshow("减去模板图后", imgCur);
-
- bool flag = m_ImageProcessing.DetectingBubble_ROI(src, templ, bubbles, ROI, canvas, true);
-
- cout << "\nmain ==== flag " << flag << endl;
- if (flag) {
- cout << "top = " << top.x << " " << top.y << endl;
- cout << "bottom = " << bottom.x << " " << bottom.y << endl;
- }
- canvas.copyTo(src);
- //cout << "\nmain ==== i " << endl;
- circle(canvas, top, 63, cv::Scalar(0, 69, 255), 1);
- circle(canvas, bottom, 63, cv::Scalar(0, 69, 255), 1);
- cv::putText(src, to_string(flag), cv::Point(src.cols / 2 - 20, src.rows / 2 - 65), cv::FONT_HERSHEY_COMPLEX, 1.75, cv::Scalar(255, 135, 160), 3);
- cv::namedWindow("main-结果图src", cv::NORMCONV_FILTER);
- cvSetMouseCallback("main-结果图src", on_mouse_singleClick, 0);
- cv::imshow("main-结果图src", src);
- cv::namedWindow("main-canvas", cv::NORMCONV_FILTER);
- cvSetMouseCallback("main-canvas", on_mouse_singleClick, 0);
- cv::imshow("main-canvas", canvas);
- }
- else
- {
- vector<string> path_name;
- getAllFiles(filePath, path_name);
- cout << "path_name.size()=" << path_name.size() << endl;
-
- int number = 1;
- for (auto i : path_name)
- {
- //cout << i.size() << endl;
- if (i.size() == 7) continue;
- if (i.find("output") != std::string::npos) continue;
- if (i.find(".log") != std::string::npos) continue;
- if (i.find(".txt") != std::string::npos) continue;
- if (i.find("png") == std::string::npos && i.find("bmp") == std::string::npos && i.find("jpg") == std::string::npos) continue;
- //if (i.find("_202404220930171") == std::string::npos) continue;
- std::string name = i;
- std::string path11 = filePath + "\\" + i;
- cv::Mat src = cv::imread(path11);
- //cv::Mat src = cv::imread(filePath + "\\" + i);
- cout << endl << "number【" << number << "】src path=" << i << " ;" << endl;
- src.copyTo(canvas);
- cv::imshow("main_OriginalIMG", src);
-
- //将结果图写入文件方便查看结果
- int len = filePath.length();
- //i = i.substr(i.find_last_of('\\') + 1, len);
- cout << "i=" << i << ", path11=" << path11 << endl;
- int time_start = clock();
- int time_end = clock();
-
- cv::Rect ROI = cv::Rect(0, 0, src.cols, src.rows);
- cv::Rect ROI = cv::Rect(tlP.x, tlP.y, brP.x - tlP.x, brP.y - tlP.y);
- if (getROI) {
- ROI = getROIFromString(name);
- }
-
- bool flag = m_ImageProcessing.DetectingBubble_ROI(src, templ, bubbles, ROI, canvas, false);
-
-
- time_end = clock();
- printf("\n耗时 %d ms \n", time_end - time_start);
- cout << "\nmain ==== flag " << flag << endl;
- if (flag) {
- cout << "top = " << top.x << " " << top.y << endl;
- cout << "bottom = " << bottom.x << " " << bottom.y << endl;
- }
- canvas.copyTo(src);
- //cv::putText(src, to_string(number - 1), { cv::Point(250, 250) }, cv::FONT_HERSHEY_COMPLEX, 8, cv::Scalar(255, 255, 255), 5);
- cv::putText(src, to_string(flag), cv::Point(src.cols / 2 - 20, src.rows / 2 - 65), cv::FONT_HERSHEY_COMPLEX, 1.75, cv::Scalar(255, 135, 160), 3);
- cv::namedWindow("main-结果图src", cv::NORMCONV_FILTER);
- cv::imshow("main-结果图src", src);
- cv::namedWindow("main-canvas", cv::NORMCONV_FILTER);
- cv::imshow("main-canvas", canvas);
-
-
- //将结果图写入文件方便查看结果
- char* filePath_ = new char[len + 1];
- strcpy(filePath_, filePath.c_str());
-
- len = filePath.length();
- char* resPath_ = new char[len + 1];
- strcpy(resPath_, resPath.c_str());
- //i.erase(0, strlen(filePath_) - strlen(resPath_) - 2);
-
- string out = filePath + resPath;
- cout << "\nmain ==== i " << i << endl;
- out.append("\\").append(i);
-
- cout << "number【" << number << "】res path=" << out << endl;
- cv::imwrite(out, src);
- number++;
-
- cout << "path_name.size() = " << path_name.size() << endl;
- cout << "*********************************************************************************************************************" << endl;
- cv::waitKey(1);
- }
- cout << "循环结束!!! main " << endl;
- }
-
- ofs.close();
- cv::waitKey(0);
- system("Pause");
- return 0;
- }
- {
- bool result = false;
- if (imgOriginal.empty()) {
- printf("传入图像为空,直接返回false!!!! \n");
- return false;
- }
- imgOriginal.copyTo(canvas);
- top = cv::Point(0, 0);
- bottom = cv::Point(0, 0);
- midP = cv::Point(0, 0);
-
- cv::Mat imgGray;
- if (imgOriginal.type() != CV_8UC1)
- cv::cvtColor(imgOriginal, imgGray, cv::COLOR_BGR2GRAY);
- else imgOriginal.copyTo(imgGray);
-
- //if (1) {
- // cv::Mat imgMedianBlur;
- // cv::medianBlur(imgGray, imgMedianBlur, 3);
- // if (debug) cv::imshow("imgMedianBlur", imgMedianBlur);
- // imgMedianBlur.copyTo(imgGray);
- //}
-
- cv::Mat close;
- cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(7, 5));
- cv::morphologyEx(imgGray, close, cv::MORPH_CLOSE, kernel);
- if (debug) cv::imshow("闭运算", close);
-
- cv::Mat thresholdMat;
- cv::adaptiveThreshold(close, thresholdMat, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C, cv::THRESH_BINARY, 85, -15);
- if (debug) cv::imshow("threshold", thresholdMat);
-
- //一个不为0的像素都没有,即全黑时,直接返回false
- int iVal255 = cv::countNonZero(thresholdMat);
- if (!iVal255) return false;
-
-
- std::vector<std::vector<cv::Point>> contours;
- std::vector<cv::Vec4i> hierarchy;
- std::vector<std::vector<cv::Point>>::iterator k;
- cv::findContours(thresholdMat, contours, hierarchy, cv::RETR_EXTERNAL, CV_RETR_LIST);
-
- if (contours.size() <= 0)//图为全黑时
- {
- std::cout << "contours.size() <= 0";
- return false;
- }
-
- if (debug) printf("图像处理后 检测到的轮廓数 contours.size() = %d \n", contours.size());
- int remainNum = 0;//剩余的轮廓数
- cv::Mat tmpMat = cv::Mat(thresholdMat.rows, thresholdMat.cols, CV_8UC1, cv::Scalar(0, 0, 0));
- //画出轮廓;
- int count = 0;
- for (k = contours.begin(); k != contours.end(); ++k, count++) //删除小连通域的
- {
- std::vector<cv::Point> curContours = *k;
- if (curContours.size() < 40) continue;
- remainNum++;
- cv::drawContours(tmpMat, contours, count, cv::Scalar(255, 255, 255), -1, CV_AA, hierarchy); //用全黑色填充
- }
- if (debug) cv::imshow("tmpMat", tmpMat);
- if (debug) printf("删减后 剩余的轮廓数 remainNum = %d \n", remainNum);
-
- if (remainNum == 0)//图为全黑时
- {
- std::cout << "contours.size() <= 0";
- return false;
- }
-
- //------------------------------------------------------------------------------------------------------------------------------------
- //提取骨干点集
-
- std::vector<cv::Point> bright_point;//max点
- std::vector<int> bright_value;//max像素值
- //bright_point = extrectBackbone(tmpMat, bright_value);
- if (1) {
- if (debug) cout << "tmpMat.size() =" << tmpMat.size() << std::endl;
- int splitRow = tmpMat.rows / 2 - 5;
- cv::Mat tmpMatU, tmpMatD;
- tmpMat.rowRange(0, splitRow).copyTo(tmpMatU);
- tmpMat.rowRange(splitRow, tmpMat.rows).copyTo(tmpMatD);
-
- cv::flip(tmpMatU, tmpMatU, 0);
-
- std::vector<cv::Point> bright_pointU;//max点
- std::vector<cv::Point> bright_pointD;//max点
- std::vector<int> bright_valueU;//max像素值
- std::vector<int> bright_valueD;//max像素值
- bright_pointU = extrectBackbone(tmpMatU, bright_valueU, 0);
- bright_pointD = extrectBackbone(tmpMatD, bright_valueD, 0);
-
- std::reverse(bright_pointU.begin(), bright_pointU.end());
- for (int i = 0; i < bright_pointU.size(); i++) {//把上半部分的骨干上下翻转回
- cv::Point curPoint = bright_pointU.at(i);
- if (curPoint.x != 0) curPoint.y = tmpMatU.rows - curPoint.y - 1;
- //if(debug) printf("将上半截骨干排序反转:第%d 行, 【%d, %d】 ============= \n", i, curPoint.x, curPoint.y);
- //curPoint.x = tmpMat.cols - curPoint.x;
- bright_point.push_back(curPoint);
- }
- std::vector<cv::Point> bright_pointD_new;
- for (int i = 0; i < bright_pointD.size(); i++) {
- cv::Point curPoint = bright_pointD.at(i);
- if (curPoint.x != 0) curPoint.y = splitRow + curPoint.y;
- bright_pointD_new.push_back(curPoint);
- }
- bright_pointD = bright_pointD_new;
-
- bright_point.insert(bright_point.end(), bright_pointD.begin(), bright_pointD.end());
-
- std::reverse(bright_valueU.begin(), bright_valueU.end());
- bright_value = bright_valueU;
- bright_value.insert(bright_value.end(), bright_valueD.begin(), bright_valueD.end());
- }
-
- //有效骨干个数过少,直接返回 false !!!!
- int vaildBackbone = 0;//有效骨干个数
- for (int i = 0; i < bright_point.size(); i++)
- {
- cv::Point P = bright_point.at(i);
- if (P != cv::Point(0, 0)) vaildBackbone++;
- }
- if (debug) printf("有效骨干个数 vaildBackbone = %d \n", vaildBackbone);
- if (vaildBackbone <= 30)
- {
- printf("有效骨干个数过少!!!!\n");
- return false;
- }
-
- if (debug) {
- printf("骨干点集更新前:\n");
- for (int i = 0; i < bright_point.size(); i++)
- {
- cv::Point curPoint = bright_point.at(i);
- int curGray = bright_value.at(i);
- //printf("骨干点集更新前:第%d 行, 【%d, %d】 灰度值:%d \n", i, curPoint.x, curPoint.y, curGray);
- }
- }
-
- std::vector<cv::Point> tmpPoint;
- std::vector<int> tmpValue;
- for (int i = 0; i < bright_point.size(); i++) {
- cv::Point curPoint = bright_point.at(i);
- if (curPoint.x == 0 || curPoint.y == 0) continue;
- if (tmpMat.at<uchar>(curPoint) < 185) continue;
- //if (imgGray.at<uchar>(curPoint) < 185) continue;
- tmpPoint.push_back(curPoint);
- }
- bright_point = tmpPoint;//把无效点删掉
-
- if (0) {
- std::vector<cv::Point> rightmost;//激光最右点集
- //for (int row = 0; row < tmpMat.rows; row++)
- //for (int row = bright_point.at(0).y; row < bright_point.at(bright_point.size() - 1).y; row++)
- for (int i = 0; i < bright_point.size(); i++)
- {
- int row = bright_point[i].y;
- //for (int col = bright_point.at(row).x; col < tmpMat.cols - 1; col++)//-1是为了防崩溃
- for (int col = bright_point.at(i).x; col < tmpMat.cols - 1 && col < bright_point.at(i).x + 70; col++)//-1是为了防崩溃
- {
- int pv = tmpMat.at<uchar>(row, col);
- //int pv = tmpMat.at<uchar>(row, col);
- if (pv != 0 && tmpMat.at<uchar>(row, col + 1) == 0)//激光最右点入列
- {
- if (!rightmost.empty() && rightmost.back().y == row) rightmost.pop_back();
- rightmost.push_back(cv::Point(col - 1, row));
- //break;
- }
- }
- }
- bright_point = rightmost;
- }
-
-
- if (debug) {
- printf("骨干点集更新后:\n");
- for (int i = 0; i < bright_point.size(); i++) {
- cv::Point curPoint = bright_point.at(i);
- printf("骨干点集更新后:第%d 行, 【%d, %d】 \n", i, curPoint.x, curPoint.y);
- }
- }
- if (debug) printf("有效骨干个数 bright_point.size() = %d \n", bright_point.size());
- if (bright_point.size() <= 30)
- {
- printf("有效骨干个数过少!!!!\n");
- return false;
- }
-
- allPntList = bright_point;
-
- //可视化骨干点集
- cv::Mat newArcMat = cv::Mat::zeros(tmpMat.size(), CV_8UC1);
- for (int i = 0; i < bright_point.size(); i++)
- {
- cv::Point P = cv::Point(bright_point.at(i).x, bright_point.at(i).y);
- newArcMat.at<uchar>(cv::Point(bright_point.at(i).x, bright_point.at(i).y)) = 255;
- }
- cv::Mat BowCurveMat;
- cv::Mat imgRGB_Begin;
- if (newArcMat.type() != CV_8UC1)
- cvtColor(newArcMat, imgRGB_Begin, cv::COLOR_RGB2GRAY);
- else newArcMat.copyTo(imgRGB_Begin);
-
-
- //重叠看效果
- cv::addWeighted(tmpMat, 0.5, imgRGB_Begin, 0.5, 0, BowCurveMat);
- //if (debug) cv::namedWindow("BowCurveMat", cv::WINDOW_NORMAL);
- if (debug) cv::imshow("BowCurveMat", BowCurveMat);
-
- result = true;
-
-
- // TODO
-
-
- return result;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。