2022-01-28

算法思路:
1圖片灰度化
2ostu閾值分割
3形態(tài)學處理,去除細小噪聲
4使用canny輪廓提取,根據(jù)面積大小作為約束條件

main.cpp


#include"Cal.h"
using namespace std;
using namespace cv;

int main(int argc, char* argv[])

{
    std::string folder_path = "D:\\Aluosang\\test.jpg"; //更改文件夾測試,或改為實時讀取圖片 img
    std::vector<cv::String> file_names;
    cv::glob(folder_path, file_names);

    cv::Mat img;

    for (int i = 0; i < file_names.size(); i++) {
        std::cout << file_names[i] << std::endl; //黑窗口輸出文件名字,如果實時更新,for循環(huán)刪改。
        img = cv::imread(file_names[i]);
        if (!img.data) {
            continue;
        }

        if (img.empty())                         // 判斷讀入圖片是否為空
        {
            cout << "image is empty" << endl;
            return -1;
        }

        /*cv::Mat src_crop = img(cv::Rect(200, 300, 700, 500)); // 裁剪后的圖 src_crop*/
        Cal ed(img);
        ed.cannyProcess(200, 220);
        ed.getContours();

        cv::imshow("img", img);  //輸出顯示
        cv::waitKey(2000);      //調(diào)時間快慢
        waitKey(0);
        return 0;
    }


   
}

Cal.cpp

#include "Cal.h"


Cal::Cal(cv::Mat image)
{
    m_img = image;
}

bool Cal::cannyProcess(unsigned int downThreshold, unsigned int upThreshold)
{
    bool ret = true;

    if (m_img.empty())
    {
        ret = false;
    }

    cv::Canny(m_img, m_canny, downThreshold, upThreshold);
    cv::imshow("Canny", m_canny);
    return ret;
}

bool Cal::getContours()
 {
       bool ret = true;
       if (m_canny.empty())
       {
               ret = false;
       }
    
        cv::Mat k = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3), cv::Point(-1, -1));
        cv::dilate(m_canny, m_canny, k);
        imshow("dilate", m_canny);
   
          // 輪廓發(fā)現(xiàn)與繪制
        vector<vector<cv::Point> > contours;
        vector<Vec4i> hierarchy;
        findContours(m_canny, contours, cv::RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
   
        for (size_t i = 0; i < contours.size(); ++i)
        {
            // 最大外接輪廓
            cv::Rect rect = cv::boundingRect(contours[i]);
            cv::rectangle(m_img, rect, cv::Scalar(0, 255, 0), 2, LINE_8);
       
          
                // 最小外接輪廓
            RotatedRect rrt = minAreaRect(contours[i]);
            Point2f pts[4];
            rrt.points(pts);
                // 繪制旋轉(zhuǎn)矩形與中心位置
            for (int i = 0; i < 4; i++) {
            line(m_img, pts[i % 4], pts[(i + 1) % 4], Scalar(0, 0, 255), 2, 8, 0);
           
            }
            Point2f cpt = rrt.center;
            circle(m_img, cpt, 2, Scalar(255, 0, 0), 2, 8, 0);
        }
   
      
        imshow("contours", m_img);
        return ret;
     }

 Cal::~Cal()
 {
     }

Cal.h


#pragma once
#include<opencv2/opencv.hpp>
#include<iostream>

using namespace std;
using namespace cv;


class Cal
{
    cv::Mat m_img;
    cv::Mat m_canny;
public:
    Cal(cv::Mat iamge);
    bool cannyProcess(unsigned int downThreshold, unsigned int upThreshold);
    bool getContours();

    ~Cal();
};

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容