您可以在形状周围绘制近似轮廓,直到连接所有需要的区域。有了这个,我有效地侵蚀了形象。如果你在这些连接区域周围画一个外壳,你会得到你的红色矩形。
重复直到你最大的三个船体有一些必要的属性(例如,如果它们覆盖了所有白点的 99%)
#include <vector>
using std::vector;
#include <algorithm>
using std::sort;
#include <string>
using std::string;
using std::to_string;
#include <iostream>
using std::clog;
using std::endl;
#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
typedef vector<Point> Polygon;
typedef vector<Polygon> Polygons;
Mat mFrame;
Mat mOrig;
mFrame = imread("R2TsZ.png");
mFrame.copyTo(mOrig);
Mat mOrigHull;
Mat mOut;
int fileCounter = 0;
while(true){
clog<< "image read"<< endl;
cvtColor(mFrame, mOut, CV_BGR2GRAY);
clog<< "image grayscaled"<< endl;
Polygons contours;
Polygons aContours;
Polygons hulls;
OutputArray hierarchy = {};
findContours(mOut, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
clog<< contours.size()<< " contours found"<< endl;
sort(contours.begin(), contours.end(), [](auto p1, auto p2){
return contourArea(p1) > contourArea(p2);
});
clog<< "contours sorted"<< endl;
aContours.resize(contours.size());
hulls.resize(contours.size());
for(size_t i = 0; i < aContours.size() - 1; ++ i){
approxPolyDP(contours[i], aContours[i], 20, true);
drawContours(mFrame, aContours, i, Scalar(255, 255, 255), 10);
convexHull(aContours[i], hulls[i], true);
}
mOrig.copyTo(mOrigHull);
for(size_t i = 0; i < 3; ++ i){
drawContours(mOrigHull, hulls, i, Scalar(0, 0, 255), 10);
}
imshow("out", mOrigHull);
int key = waitKey() & 0xff;
if(key == 27){
return EXIT_SUCCESS;
}
if(key == 'p'){
string file = "test_" + to_string(++ fileCounter) + ".png";
imwrite(file, mOrigHull);
clog<< file<< " saved."<< endl;
}
}
}
在opencv的本教程中查看更多信息。