7 FileStorage fs(
"statics/params.xml", FileStorage::READ);
10 cout <<
"Open file failed" << endl;
13 FileNode node = fs[
"armour_detector"];
34 vector<vector<Point> > blocks =
searchBlocks(dstImage.clone());
40 Mat drawImage = srcImage.clone();
43 drawBlocks(drawImage, lampBlocks, Scalar(200, 150, 100));
49 drawBlocks(drawImage, armourBlocks, Scalar(100, 150, 200));
51 if(armourBlocks.empty())
61 if(armourBlocks.empty())
76 for(
unsigned int i = 0; i < minRotatedRects.size(); i++)
79 minRotatedRects[i].points(points);
81 for(
unsigned int j = 0; j < 4; j++)
83 line(srcImage, points[j], points[(j+1)%4], color, 2);
87 imshow(
"detectBlocks", srcImage);
95 if(row < 0 || row >= srcImage.rows || col < 0 || col >= srcImage.cols || srcImage.at<uchar>(row, col) == 0)
101 blocks.back().push_back(Point(col, row));
103 srcImage.at<uchar>(row, col) = 0;
105 for(
int x = -1; x <= 1; x++)
107 for(
int y = -1; y <= 1; y++)
122 vector<vector<Point> > blocks;
124 int rowNum = srcImage.rows;
125 int colNum = srcImage.cols;
128 if (srcImage.isContinuous())
131 colNum = colNum * srcImage.rows * srcImage.channels();
134 for (
int row = 0; row < rowNum; row++)
136 uchar* srcImagePtr = srcImage.ptr<uchar>(row);
138 for (
int col = 0; col < colNum; col++)
144 blocks.push_back(vector<Point>());
148 fillLampBlock(srcImage, blocks, col/srcImage.cols, col%srcImage.cols);
163 vector<RotatedRect> lampBlocks;
165 for(
unsigned int i = 0; i < blocks.size(); i++)
167 RotatedRect minRotatedRect = minAreaRect(blocks[i]);
177 lampBlocks.push_back(minRotatedRect);
186 vector<RotatedRect> armourBlocks;
189 if(lampBlocks.empty())
194 for(
unsigned int i = 0; i < lampBlocks.size() - 1; i++)
196 for(
unsigned int j = i + 1; j < lampBlocks.size(); j++)
198 if(fabs(lampBlocks[i].boundingRect2f().width-lampBlocks[j].boundingRect2f().width) <=
params.
maxWidthRat * lampBlocks[i].boundingRect2f().width
199 && fabs(lampBlocks[i].boundingRect2f().height-lampBlocks[j].boundingRect2f().height) <=
params.
maxHeightRat * lampBlocks[i].boundingRect2f().height
203 distance += powf((lampBlocks[i].center.x-lampBlocks[j].center.x), 2);
204 distance += powf((lampBlocks[i].center.y-lampBlocks[j].center.y), 2);
205 distance = sqrt(distance);
208 && fabs(lampBlocks[i].center.y-lampBlocks[j].center.y) < 2 * lampBlocks[i].boundingRect2f().height)
210 vector<Point> points;
211 Point2f iPoints[4], jPoints[4];
212 lampBlocks[i].points(iPoints);
213 lampBlocks[j].points(jPoints);
214 for(
unsigned int k = 0; k < 4; k++)
216 points.push_back(iPoints[k]);
217 points.push_back(jPoints[k]);
220 RotatedRect minRotatedRect = minAreaRect(points);
221 if((minRotatedRect.size.height > minRotatedRect.size.width && minRotatedRect.angle < -60)
222 || (minRotatedRect.size.height < minRotatedRect.size.width && minRotatedRect.angle > -30))
224 armourBlocks.push_back(minRotatedRect);
232 cout <<
"Num of lampBlocksRects: " << armourBlocks.size() << endl;
244 threshold(dstImage, invDstImage, 0, 255, THRESH_BINARY_INV);
246 for(
unsigned int id = 0;
id < armourBlocks.size();
id++)
249 armourBlocks[id].points(fpoints);
256 for(
unsigned int i = 0; i < 4; i++)
258 points[i] = Point(static_cast<int>(fpoints[i].x), static_cast<int>(fpoints[i].y));
261 const Point* pts = points;
265 Mat mask(srcImage.size(), CV_8UC1, Scalar(0));
267 fillConvexPoly(mask, pts, npts, Scalar(255));
269 bitwise_and(mask, invDstImage, mask);
271 Scalar armourBlockMean, armourBlockStdDev;
272 meanStdDev(srcImage, armourBlockMean, armourBlockStdDev, mask);
273 double grade = sqrt((pow(armourBlockMean[0], 2) + pow(armourBlockMean[1], 2) + pow(armourBlockMean[2], 2))/3.0) + 5 * sqrt((pow(armourBlockStdDev[0], 2) + pow(armourBlockStdDev[1], 2) + pow(armourBlockStdDev[2], 2))/3.0);
274 imshow(
"mask", mask);
287 for(
unsigned int i = 0; i < 4; i++)
289 centerx += points[i].x;
294 vector<Point2f> leftPoints;
295 vector<Point2f> rightPoints;
296 for(
unsigned int i = 0; i < 4; i++)
298 if(points[i].x < centerx)
300 leftPoints.push_back(points[i]);
304 rightPoints.push_back(points[i]);
309 if(leftPoints[0].y < leftPoints[1].y)
311 reverse(leftPoints.begin(), leftPoints.end());
314 if(rightPoints[0].y < rightPoints[1].y)
316 reverse(rightPoints.begin(), rightPoints.end());
320 if(leftPoints[1].y > rightPoints[1].y)
325 newPoint.x = leftPoints[0].x;
326 newPoint.y = (leftPoints[1].y-rightPoints[1].y)/(leftPoints[1].x-rightPoints[1].x)
327 * (leftPoints[0].x-rightPoints[1].x) + rightPoints[1].y;
328 leftPoints[1] = newPoint;
330 newPoint.x = rightPoints[1].x;
331 newPoint.y = (leftPoints[0].y-rightPoints[0].y)/(leftPoints[0].x-rightPoints[0].x)
332 * (rightPoints[1].x-leftPoints[0].x) + leftPoints[0].y;
333 rightPoints[0] = newPoint;
340 newPoint.x = leftPoints[1].x;
341 newPoint.y = (leftPoints[0].y-rightPoints[0].y)/(leftPoints[0].x-rightPoints[0].x)
342 * (leftPoints[1].x-rightPoints[0].x) + rightPoints[0].y;
343 leftPoints[0] = newPoint;
345 newPoint.x = rightPoints[0].x;
346 newPoint.y = (leftPoints[1].y-rightPoints[1].y)/(leftPoints[1].x-rightPoints[1].x)
347 * (rightPoints[0].x-leftPoints[1].x) + leftPoints[1].y;
348 rightPoints[1] = newPoint;
352 points[0] = leftPoints[0];
353 points[1] = leftPoints[1];
354 points[2] = rightPoints[1];
355 points[3] = rightPoints[0];
Mat preprocess(const Mat &srcImage)
对读取到的图片预处理
bool detect(const Mat &srcImage)
检测图像中是否存在装甲板区域
vector< vector< Point > > searchBlocks(Mat srcImage)
搜寻图中所有独立的团块
HLL Computer Vision Code namepace.
void cutEdgeOfRect(Point2f *points)
减去旋转矩形的边角,使旋转矩形的左右两条边与竖直方向平行,成为平行四边形
void markArmourBlocks(const Mat &srcImage, const Mat &dstImage, const vector< RotatedRect > &armourBlocks)
对最后提取出的灯柱区域评分,选出最优区域
struct HCVC::ArmourDetector::Params params
void drawBlocks(Mat srcImage, const vector< RotatedRect > &minRotatedRects, const Scalar &color) const
在原图像上画出旋转矩形,便于调试
vector< RotatedRect > calcBlocksInfo(const vector< vector< Point > > &blocks)
计算每一个团块的信息,并进行初步的筛选即去除掉一些不符合条件的团块
void fillLampBlock(Mat &srcImage, vector< vector< Point > > &blocks, int row, int col)
用广度优先搜索填充每一个连通块
ArmourDetector()
加载装甲板区域判定参数
Rect2d getBestArmourBlock() const
获取上一次图像中检测出的最佳装甲板区域
vector< OptimalArmourBlock > optimalArmourBlocks
vector< RotatedRect > extracArmourBlocks(const vector< RotatedRect > &minRotatedRects)
进一步筛选,匹配团块即灯柱对,提取出最优目标