OpenCV 绘制轮廓


#include <opencv2/opencv.hpp>
#include <vector>

// 全局变量
cv::Mat src, copy, dst, gray;
std::vector<std::vector<cv::Point>> contours;
//std::vector<cv::Point> lines;
std::vector<cv::Point> lines;
bool drawing = false;
cv::Point prevPoint;
cv::Point firstPoint;
// 鼠标回调函数
static void mouseHandler(int event, int x, int y, int flags, void* userData) {
    if (event == cv::EVENT_LBUTTONDOWN) {
        drawing = true;
        std::vector<cv::Point>().swap(lines);
        prevPoint = cv::Point(x, y);
        firstPoint = cv::Point(x, y);
        lines.push_back(prevPoint);
        
    }
    else if (event == cv::EVENT_MOUSEMOVE && flags == cv::EVENT_FLAG_LBUTTON) {
        if (drawing) {
            cv::Point pt(x, y);
            cv::line(dst, prevPoint, pt, cv::Scalar(255, 0, 0), 1, 8, 0);
            cv::line(gray, prevPoint, pt, cv::Scalar(255, 255, 255), 1, 8, 0);
            prevPoint = pt;
            lines.push_back(pt);
            
        }
    }
    else if (event == cv::EVENT_LBUTTONUP) {
        drawing = false;
        cv::Point pt(x, y);
        cv::line(dst, prevPoint, pt, cv::Scalar(255, 0, 0), 1, 8, 0);
        cv::line(gray, prevPoint, pt, cv::Scalar(255, 255, 255), 1, 8, 0);
        cv::line(dst, pt, firstPoint, cv::Scalar(255, 0, 0), 1, 8, 0);
        cv::line(gray, pt, firstPoint, cv::Scalar(255, 255, 255), 1, 8, 0);
        lines.push_back(pt);
        contours.push_back(lines);

    }
}
std::vector<cv::Scalar> colors =
{
    cv::Scalar(0, 0, 255),
    cv::Scalar(0, 255, 0),
    cv::Scalar(255, 0, 0),
    cv::Scalar(255, 255, 0),
    cv::Scalar(0, 255, 255),
    cv::Scalar(255, 0, 255)
};
int main() {
    std::string path = "D:/500_1s.png";
    src = cv::imread(path); // 替换为你的图片路径
    cv::resize(src, src, cv::Size(600, 600));
    dst = src.clone();
    copy = src.clone();

    cv::cvtColor(dst, gray, cv::COLOR_BGR2GRAY);
    gray.setTo(cv::Scalar(0));

    cv::namedWindow("Drawing");
    cv::setMouseCallback("Drawing", mouseHandler, 0);

    while (true) {
        cv::imshow("Drawing", dst);
        cv::imshow("gray", gray);
        
        int key = cv::waitKey(1);
        if (key == 'r') { // 按 'r' 重置
            dst = src.clone();
            contours.clear();
            gray.setTo(cv::Scalar(0));
        }
        else if (key == 27) { // 按 'ESC' 退出
            break;
        }

        if (!contours.empty())
        {
            for (int i = 0; i < contours.size(); ++i)
            {
                std::vector<std::vector<cv::Point>> ct;
                ct.push_back(contours[i]);
                cv::Scalar color = colors[i% colors.size()];
                std::string contour_name = "contours_" + std::to_string(i);
                cv::Mat contourImage = cv::Mat::zeros(gray.size(), CV_8UC1);
                cv::drawContours(contourImage, ct, -1, cv::Scalar(255, 255, 255), -1); // -1 表示填充轮廓内部
                std::vector<cv::Point> nonZeroCoords;
                cv::findNonZero(contourImage, nonZeroCoords);
                for (int i = 0; i < nonZeroCoords.size(); ++i)
                {
                    cv::circle(copy, nonZeroCoords[i], 1, color, cv::FILLED);
                }
            }
            cv::imshow("copy", copy);
        }
    }

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值