void PMRoadGenerator::setupTensor(const Polygon2D& targetArea, const std::vector<std::pair<QVector2D, float>>& regular_elements, cv::Mat& tensor) { BBox bbox = targetArea.envelope(); tensor = cv::Mat(bbox.dy() + 1, bbox.dx() + 1, CV_32F); for (int r = 0; r < tensor.rows; ++r) { for (int c = 0; c < tensor.cols; ++c) { int x = c + bbox.minPt.x(); int y = r + bbox.minPt.y(); double total_angle = 0.0; double total_weight = 0.0; for (int k = 0; k < regular_elements.size(); ++k) { float dist = (QVector2D(x, y) - regular_elements[k].first).length(); double angle = regular_elements[k].second; double weight = exp(-dist / 10); total_angle += angle * weight; total_weight += weight; } float avg_angle = total_angle / total_weight; tensor.at<float>(r, c) = avg_angle; } } }
void VBOPmBlocks::saveBlockImage(RoadGraph& roads, Polygon3D& contour, const char* filename) { BBox bbox = GraphUtil::getAABoundingBox(roads, true); cv::Mat img(bbox.dy() + 1, bbox.dx() + 1, CV_8UC3, cv::Scalar(255, 255, 255)); RoadEdgeIter ei, eend; for (boost::tie(ei, eend) = boost::edges(roads.graph); ei != eend; ++ei) { if (!roads.graph[*ei]->valid) continue; for (int pl = 0; pl < roads.graph[*ei]->polyline.size() - 1; ++pl) { int x1 = roads.graph[*ei]->polyline[pl].x() - bbox.minPt.x(); int y1 = img.rows - (roads.graph[*ei]->polyline[pl].y() - bbox.minPt.y()); int x2 = roads.graph[*ei]->polyline[pl + 1].x() - bbox.minPt.x(); int y2 = img.rows - (roads.graph[*ei]->polyline[pl + 1].y() - bbox.minPt.y()); cv::line(img, cv::Point(x1, y1), cv::Point(x2, y2), cv::Scalar(224, 224, 224), 3); } } for (int i = 0; i < contour.contour.size(); ++i) { int next = (i + 1) % contour.contour.size(); int x1 = contour.contour[i].x() - bbox.minPt.x(); int y1 = img.rows - (contour.contour[i].y() - bbox.minPt.y()); int x2 = contour.contour[next].x() - bbox.minPt.x(); int y2 = img.rows - (contour.contour[next].y() - bbox.minPt.y()); cv::line(img, cv::Point(x1, y1), cv::Point(x2, y2), cv::Scalar(0, 0, 0), 3); } cv::imwrite(filename, img); }
void PMRoadGenerator::saveRoadImage(RoadGraph& roads, const std::string& filename) { BBox bbox; RoadVertexIter vi, vend; for (boost::tie(vi, vend) = boost::vertices(roads.graph); vi != vend; ++vi) { if (!roads.graph[*vi]->valid) continue; bbox.addPoint(roads.graph[*vi]->pt); } cv::Mat result((int)(bbox.dy() + 1), (int)(bbox.dx() + 1), CV_8UC3, cv::Scalar(255, 255, 255)); RoadEdgeIter ei, eend; for (boost::tie(ei, eend) = boost::edges(roads.graph); ei != eend; ++ei) { if (!roads.graph[*ei]->valid) continue; for (int k = 0; k < roads.graph[*ei]->polyline.size() - 1; ++k) { int x1 = roads.graph[*ei]->polyline[k].x() - bbox.minPt.x(); int y1 = roads.graph[*ei]->polyline[k].y() - bbox.minPt.y(); int x2 = roads.graph[*ei]->polyline[k + 1].x() - bbox.minPt.x(); int y2 = roads.graph[*ei]->polyline[k + 1].y() - bbox.minPt.y(); cv::line(result, cv::Point(x1, y1), cv::Point(x2, y2), cv::Scalar(0, 0, 0), 1, cv::LINE_AA); } } for (boost::tie(vi, vend) = boost::vertices(roads.graph); vi != vend; ++vi) { if (!roads.graph[*vi]->valid) continue; int count = 0; RoadOutEdgeIter oi, oend; for (boost::tie(oi, oend) = boost::out_edges(*vi, roads.graph); oi != oend; ++oi) { if (roads.graph[*oi]->valid) count++; } if (count == 2) continue; int x = roads.graph[*vi]->pt.x() - bbox.minPt.x(); int y = roads.graph[*vi]->pt.y() - bbox.minPt.x(); cv::circle(result, cv::Point(x, y), 5, cv::Scalar(255, 0, 0), 1, cv::LINE_AA); QString text = QString::number(count); cv::putText(result, text.toUtf8().constData(), cv::Point(x, y), cv::FONT_HERSHEY_PLAIN, 2, cv::Scalar(0, 0, 0), 1, cv::LINE_AA); } cv::imwrite(filename.c_str(), result); }
/** * KDEベースでの特徴量を抽出する。 */ void KDEFeatureExtractor::extractFeature(RoadGraph& roads, Polygon2D& area, RoadFeature& roadFeature) { roadFeature.clear(); KDEFeaturePtr kf = KDEFeaturePtr(new KDEFeature(0)); QVector2D center = area.envelope().midPt(); /////////////////////////////////////////////////////////////////////////////////////////////////////// // Avenueのみを抽出する RoadGraph temp_roads; time_t start = clock(); GraphUtil::copyRoads(roads, temp_roads); time_t end = clock(); std::cout << "Elapsed time for copying the roads: " << (double)(end-start)/CLOCKS_PER_SEC << " [sec]" << std::endl; if (G::getBool("exactCut")) { GraphUtil::extractRoads2(temp_roads, area); } start = clock(); GraphUtil::extractRoads(temp_roads, RoadEdge::TYPE_AVENUE | RoadEdge::TYPE_BOULEVARD); end = clock(); std::cout << "Elapsed time for extracting only the avenues: " << (double)(end-start)/CLOCKS_PER_SEC << " [sec]" << std::endl; start = clock(); GraphUtil::clean(temp_roads); end = clock(); std::cout << "Elapsed time for cleaning the avenues: " << (double)(end-start)/CLOCKS_PER_SEC << " [sec]" << std::endl; start = clock(); //GraphUtil::reduce(temp_roads); end = clock(); std::cout << "Elapsed time for reducing the avenues: " << (double)(end-start)/CLOCKS_PER_SEC << " [sec]" << std::endl; // roundaboutを削除する //GraphUtil::removeRoundabout(temp_roads); // linkを削除する start = clock(); GraphUtil::removeLinkEdges(temp_roads); end = clock(); std::cout << "Elapsed time for removing links: " << (double)(end-start)/CLOCKS_PER_SEC << " [sec]" << std::endl; start = clock(); //GraphUtil::reduce(temp_roads); end = clock(); std::cout << "Elapsed time for reducing links: " << (double)(end-start)/CLOCKS_PER_SEC << " [sec]" << std::endl; GraphUtil::removeIsolatedVertices(temp_roads); start = clock(); GraphUtil::clean(temp_roads); end = clock(); std::cout << "Elapsed time for cleaning the avenues: " << (double)(end-start)/CLOCKS_PER_SEC << " [sec]" << std::endl; // 特徴量を抽出 int num_vertices = extractAvenueFeature(temp_roads, area, kf); if (G::getBool("perturbation")) { extractAvenueFeature(temp_roads, area, kf, true); } BBox bbox = area.envelope(); std::cout << "Area: " << area.area() << std::endl; std::cout << "BBox: " << bbox.dx() << "," << bbox.dy() << std::endl; std::cout << "Num avenue vertices: " << num_vertices << std::endl; kf->setDensity(RoadEdge::TYPE_AVENUE, num_vertices / area.area()); /////////////////////////////////////////////////////////////////////////////////////////////////////// // streetのみを抽出する start = clock(); GraphUtil::copyRoads(roads, temp_roads); end = clock(); std::cout << "Elapsed time for copying the roads: " << (double)(end-start)/CLOCKS_PER_SEC << " [sec]" << std::endl; if (G::getBool("exactCut")) { GraphUtil::extractRoads2(temp_roads, area); } start = clock(); GraphUtil::extractRoads(temp_roads, RoadEdge::TYPE_STREET); end = clock(); std::cout << "Elapsed time for extracting the streets: " << (double)(end-start)/CLOCKS_PER_SEC << " [sec]" << std::endl; //GraphUtil::reduce(temp_roads); <- わざとreduceしない // linkを削除する start = clock(); GraphUtil::removeLinkEdges(temp_roads); end = clock(); std::cout << "Elapsed time for removing links: " << (double)(end-start)/CLOCKS_PER_SEC << " [sec]" << std::endl; GraphUtil::removeIsolatedVertices(temp_roads); start = clock(); GraphUtil::clean(temp_roads); end = clock(); std::cout << "Elapsed time for cleaning the streets: " << (double)(end-start)/CLOCKS_PER_SEC << " [sec]" << std::endl; // 特徴量を抽出 num_vertices = extractStreetFeature(temp_roads, area, kf); if (G::getBool("perturbation")) { extractStreetFeature(temp_roads, area, kf, true); } kf->setDensity(RoadEdge::TYPE_STREET, num_vertices / area.area()); kf->setWeight(1.0f); kf->setCenter(center); // 領域を少しだけ大きくする。これにより、抽出された道路網の交差点が、確実に領域内と判定されるはず。 for (int i = 0; i < area.size(); ++i) { area[i] = (area[i] - center) * 1.02f + center; } kf->setArea(area); roadFeature.addFeature(kf); }