記事のディレクトリ
1.ステップ
- 二値画像閾値に最初の画像()
- ディスカバリープロフィール、画像プロファイルキャニーを見つけます()
- 最小外接矩形や円、四角形および楕円回転の輪郭点で利用可能な関連するAPIを介し。
- それらを描画します。長方形()またはサークル()
2.関連API
2.1 approxPolyDP()
- 多角形の輪郭点を低減する目的に基づいて、RDPアルゴリズム
2.2のcv :: boundingRect()
- 最小矩形を左上座標と輪郭線の周りの交点座標の右下隅を与えるためには、四角形を描画します
2.3のcv :: minAreaRect()
返された矩形を回転、回転の矩形を得ました。
2.4のcv :: minEnclosingCircle()
- 円形の最小面積を得るために
2.5馬力:: fitEllipse()
- 最小楕円形を与えるために、
3.ルーチン
#include<opencv2/opencv.hpp>
#include<iostream>
#include<math.h>
using namespace cv;
using namespace std;
void CallBack(int, void*);
Mat src, dst, binout, src_gray;
int Threshold = 40;
int main() {
//输入图像并转化为灰度
src = imread("D:/resource/images/硬币.jpg");
if (src.empty()) {
printf("src couldn't be loaded...");
return -1;
}
imshow("input", src);
cvtColor(src, src_gray, COLOR_BGR2GRAY);
medianBlur(src_gray, src_gray, 21);
blur(src_gray, src_gray, Size(21, 21));
//设置阈值后执行CallBack()
namedWindow("output");
createTrackbar("Threshold", "output", &Threshold, 255, CallBack);
CallBack(0, 0);
waitKey(0);
return 0;
}
void CallBack(int, void*) {
//二值化
threshold(src_gray, binout, Threshold, 255, THRESH_BINARY);
//Canny(src_gray, binout, Threshold, Threshold * 2);
imshow("binary", ~binout);
//寻找边缘
vector<vector<Point>> contours;
vector<Vec4i> hierachy;
findContours(binout, contours, hierachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
//得到矩形框和圆形框和椭圆框的的相关参数
vector<vector<Point>> polies(contours.size());//减少后的多边形边缘上的点
vector<Rect> rects(contours.size());//矩形框
vector<Point2f> ccs(contours.size());//圆心
vector<float> radius(contours.size());//圆的半径
vector<RotatedRect> rotatedRects(contours.size());//旋转矩形框
vector<RotatedRect> rotatedEllipces(contours.size());//旋转椭圆框
for (size_t i = 0; i < contours.size(); i++) {
approxPolyDP(Mat(contours[i]), polies[i], 3, true);//减少多边形边缘点
rects[i] = boundingRect(polies[i]);
minEnclosingCircle(polies[i], ccs[i], radius[i]);
if (polies[i].size() > 5) {//旋转矩形和椭圆检测点至少需要5个
rotatedEllipces[i] = fitEllipse(polies[i]);
rotatedRects[i] = minAreaRect(polies[i]);
}
}
//绘制他们
Point2f pts[4];
for (size_t i = 0; i < contours.size(); i++) {
rectangle(src, rects[i], Scalar(255, 0, 0), 2);//画矩形框
circle(src, ccs[i], radius[i], Scalar(0, 255, 255), 2, 8);//画圆
if (polies.size() > 5) {
ellipse(src, rotatedEllipces[i], Scalar(0, 0, 255), 2, 8);//画旋转椭圆
rotatedRects[i].points(pts);//画旋转矩形
for (int k = 0; k < 4; k++)
line(src, pts[k], pts[(k + 1) % 4], Scalar(255, 255, 0), 2, 8);
}
}
imshow("output", src);
return;
}