我使用了互联网上某人的密码。我正在尝试从图像中找到矩形坐标。我成功地在图像中找到矩形并在其上绘制线条。经过这些过程后,我尝试从图像中的每个矩形中找到坐标 例如[x1:1,y1:1],[x2:1,y2:2] .... [x4:4,y4:6]
这是我的项目工作方式的图片 https://i.imgur.com/oB5tYac.jpg
这是我想要我的项目工作的图像: https://i.imgur.com/QkFbCgN.jpg
我认为如果可以使用数组“ approx”,那就有解决方案。 也许没有..请帮助我。
#include "opencv2/opencv.hpp"
#include <iostream>
#include <string>
using namespace cv;
using namespace std;
void CallBackFunc(int event, int x, int y, int flags, void* userdata) {
if (event == EVENT_LBUTTONDOWN)
printf("LBUTTON_DOWN down %d %d \n", x, y);
else if (event == EVENT_RBUTTONDOWN)
printf("RBUTTON_DOWN down %d %d \n", x, y);
else if (event == EVENT_MBUTTONDOWN)
printf("MBUTTON_DOWN down %d %d \n", x, y);
}
//Contour 영역 내에 텍스트 쓰기
void setLabel(Mat& image, string str, vector<Point> contour)
{
int fontface = FONT_HERSHEY_SIMPLEX;
double scale = 0.5;
int thickness = 1;
int baseline = 0;
Size text = getTextSize(str, fontface, scale, thickness, &baseline);
Rect r = boundingRect(contour);
Point pt(r.x + ((r.width - text.width) / 2), r.y + ((r.height + text.height) / 2));
rectangle(image, pt + Point(0, baseline), pt + Point(text.width, -text.height), CV_RGB(200, 200, 200), FILLED);
putText(image, str, pt, fontface, scale, CV_RGB(0, 0, 0), thickness, 8);
printf("x값 : %d\n",r.x);
printf("y값 : %d\n", r.y);
}
int main(int, char**)
{
Mat img_input, img_result, img_gray;
//이미지파일을 로드하여 image에 저장
img_input = imread("pipe.jpg", IMREAD_COLOR);
if (img_input.empty())
{
cout << "Could not open or find the image" << std::endl;
return -1;
}
resize(img_input, img_input, Size(0, 0), 0.25, 0.25, INTER_LINEAR);
//그레이스케일 이미지로 변환
cvtColor(img_input, img_gray, COLOR_BGR2GRAY);
//이진화 이미지로 변환
Mat binary_image;
threshold(img_gray, img_gray, 128, 255, THRESH_BINARY_INV | THRESH_OTSU);
//contour를 찾는다.
vector<vector<Point> > contours;
findContours(img_gray, contours, RETR_LIST, CHAIN_APPROX_SIMPLE);
//contour를 근사화한다.
vector<Point2f> approx;
img_result = img_input.clone();
for (size_t i = 0; i < contours.size(); i++)
{
approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true) * 0.02, true);
if (fabs(contourArea(Mat(approx))) > 400) {
int size = approx.size();
//Contour를 근사화한 직선을 그린다.
if (size % 2 == 0) {
line(img_result, approx[0], approx[approx.size() - 1], Scalar(0, 255, 0), 1);
for (int k = 0; k < size - 1; k++)
line(img_result, approx[k], approx[k + 1], Scalar(0, 255, 0), 1);
for (int k = 0; k < size; k++){
circle(img_result, approx[k], 3, Scalar(0, 0, 255));
}
}
else {
line(img_result, approx[0], approx[approx.size() - 1], Scalar(0, 255, 0), 1);
for (int k = 0; k < size - 1; k++)
line(img_result, approx[k], approx[k + 1], Scalar(0, 255, 0), 1);
for (int k = 0; k < size; k++){
circle(img_result, approx[k], 3, Scalar(0, 0, 255));
}
}
//도형을 판정한다.
if (size == 3)
setLabel(img_result, "triangle", contours[i]); //삼각형
//이하는 해당 꼭지점을 가진 convex라면 찾는 도형
else if (size == 4 && isContourConvex(Mat(approx)))
setLabel(img_result, "rectangle", contours[i]); //사각형
else if (size == 5 && isContourConvex(Mat(approx)))
setLabel(img_result, "pentagon", contours[i]); //오각형
else if (size == 6 && isContourConvex(Mat(approx)))
setLabel(img_result, "hexagon", contours[i]); //육각형
else if (size == 10 && isContourConvex(Mat(approx)))
setLabel(img_result, "decagon", contours[i]); //십각형
}
}
namedWindow("img", 0);
setMouseCallback("img", CallBackFunc, NULL);
imshow("input", img_input);
imshow("img", img_result);
waitKey(0);
destroyAllWindows();
return 0;
}