算法思路:
1圖片灰度化
2ostu閾值分割
3形態(tài)學(xué)處理,去除細(xì)小噪聲
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"; //更改文件夾測試,或改為實(shí)時(shí)讀取圖片 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; //黑窗口輸出文件名字,如果實(shí)時(shí)更新,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)時(shí)間快慢
? ? ? ? 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();
};
```