OpenCV学习心得2

目录

7月21日

对图像进行二值化并画出轮廓

 7月23日

对特定的物体进行轮廓标注

寻找机甲的中心点


7月21日

今天的任务是使用OpenCV进行轮廓识别,并标出机甲的中心位置

对图像进行二值化并画出轮廓

任务中没有要求这一项,我自己先试了一下

#include <opencv2/opencv.hpp>
#include <iostream>
#include <string>
using namespace cv;
using namespace std;


int main() {
    Mat img = imread("/Users/milkman/Desktop/图片 1.png");
    Mat img_gray;
    cvtColor(img, img_gray, COLOR_BGR2GRAY);
    Mat thresh;
    threshold(img_gray, thresh, 200, 255, THRESH_BINARY);
    imshow("Binary mage", thresh);
    waitKey(0);
    vector<vector<Point>> contours;
    vector<Vec4i> hierarchy;
    findContours(thresh, contours, hierarchy, RETR_TREE, CHAIN_APPROX_NONE);
    Mat image_copy = img.clone();
    drawContours(image_copy, contours, -1, Scalar(0, 255, 0), 2);
    imshow("None approximation", image_copy);
    waitKey(0);
    imwrite("/Users/milkman/Desktop/contours_none_image1.jpg", image_copy);
    destroyAllWindows();

    return 0;
}

其中threshold的第三和第四个参数指的是将RGB值200以上的像素点都赋予255值

实现效果如下

 7月23日

接上续,这两天有点事

可以看到标出的轮廓并不都是我们想要的,经过优化threshold函数后也依然不理想,可能要经过后续的学习(待填坑)

对特定的物体进行轮廓标注

#include <opencv2/opencv.hpp>
#include <iostream>
#include <string>
using namespace cv;
using namespace std;
bool Contour_Area(vector<Point> contour1, vector<Point> contour2)
{
    return contourArea(contour1) > contourArea(contour2);
}

int main() {
    Mat img = imread("/Users/milkman/Desktop/3.png");
    Mat img_gray;

    vector<vector<Point>> contours;
    vector<Vec4i> hierarchy;
    cvtColor(img, img_gray, COLOR_BGR2GRAY);
    bool ret = false;
    findContours(img_gray, contours, hierarchy, RETR_TREE, CHAIN_APPROX_NONE, Point(0,0));
    sort(contours.begin(), contours.end(), Contour_Area);
    for (int i = 0; i < contours.size(); i++)
    {
        double area = contourArea(contours[i]);
        cout << area << endl;
    }
    Point2f P1[4], P2[4];
    RotatedRect rectleft = minAreaRect(contours[2]);
    rectleft.points(P1);
    RotatedRect rectright = minAreaRect(contours[6]);
    rectright.points(P2);
    cvtColor(img_gray, img, COLOR_GRAY2BGR);
    for (int i = 0; i <= 3; i++)
    {
        line(img, P1[i], P1[(i + 1) % 4], Scalar(0, 255, 255), 5);
    }
    for (int i = 0; i <= 3; i++)
    {
        line(img, P2[i], P2[(i + 1) % 4], Scalar(0, 255, 255), 5);
    }
    imshow("test", img);
    waitKey(0);
    destroyAllWindows();

    return 0;
}

实现这个功能的重点是对每个轮廓进行标号,如果不标号的话需要遍历,如下图

会错误地进行标注。

我采用的是用面积标号,参考了网上的代码(自己暂时还写不出来)但是似乎遇到了bug,猜测可能是面积的计算出了问题,contours数组里的元素竟然超过了6个。

 

 如果有大佬能够解决,希望能跟我交流一下

寻找机甲的中心点

    Point2f mid[1];
    mid[0].x = ((P1[0].x + P1[2].x) / 2 + (P2[0].x + P2[2].x) / 2) / 2;
    mid[0].y = ((P1[0].y + P1[2].y) / 2 + (P2[0].y + P2[2].y) / 2) / 2;
    circle(img, m[0], 10, Scalar(0, 255, 255), -1);

效果如下

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值