Commit 5e69f8fca9d5597af539904e4b67bae1f9c2bfc8

Authored by Hu Chunming
1 parent 81e8a405

补充字段;

优化逆行处理
jni/VehicleNativeInterface.cpp
@@ -452,7 +452,7 @@ JNIEXPORT jint JNICALL Java_com_objecteye_nativeinterface_vehicle_VehicleNativeI @@ -452,7 +452,7 @@ JNIEXPORT jint JNICALL Java_com_objecteye_nativeinterface_vehicle_VehicleNativeI
452 jobject vehicle_pendant_det_res_vpd_res_syRect_rect = env->NewObject(cls_SyRect, mid_SyRect, one_pendant_res.rect.left_, 452 jobject vehicle_pendant_det_res_vpd_res_syRect_rect = env->NewObject(cls_SyRect, mid_SyRect, one_pendant_res.rect.left_,
453 one_pendant_res.rect.top_, one_pendant_res.rect.width_, one_pendant_res.rect.height_); 453 one_pendant_res.rect.top_, one_pendant_res.rect.width_, one_pendant_res.rect.height_);
454 454
455 - jobject vehiclePendantDetInfo = env->NewObject(cls_VehiclePendantDetInfo, mid_VehiclePendantDetInfo, vehicle_pendant_det_res_vpd_res_syRect_rect, one_pendant_res.index, one_pendant_res.confidence, one_pendant_res.driver_copilot_info); 455 + jobject vehiclePendantDetInfo = env->NewObject(cls_VehiclePendantDetInfo, mid_VehiclePendantDetInfo, vehicle_pendant_det_res_vpd_res_syRect_rect, one_pendant_res.index, one_pendant_res.confidence, one_pendant_res.driver_copilot_info, one_pendant_res.iColor);
456 456
457 env->SetObjectArrayElement(vehiclePendantDetInfoArray, m, vehiclePendantDetInfo); 457 env->SetObjectArrayElement(vehiclePendantDetInfoArray, m, vehiclePendantDetInfo);
458 } 458 }
@@ -530,7 +530,18 @@ JNIEXPORT jint JNICALL Java_com_objecteye_nativeinterface_vehicle_VehicleNativeI @@ -530,7 +530,18 @@ JNIEXPORT jint JNICALL Java_com_objecteye_nativeinterface_vehicle_VehicleNativeI
530 } 530 }
531 531
532 jint type = vehicle_info.type; 532 jint type = vehicle_info.type;
533 - jobject vehicleInfo = env->NewObject(cls_VehicleInfo, mid_VehicleInfo, vehicleDetectResult, vehicleWinDetectResult, vehicleBodyDetectResult, vehicleColorResult, vehicleRecgResult, vplateResult, vehiclePendantDetResult, vehicleIllegalDetResult, vehicleFeaResult,mtaResult, MannedResult, type ); 533 + jint vpt_type = vehicle_info.vpt_type;
  534 + jint rainshed = vehicle_info.rainshed; //是否安装雨棚, 0 有雨棚 1 无雨棚
  535 + jint truck_manned = vehicle_info.truck_manned;
  536 + jint motor_manned = vehicle_info.motor_manned;
  537 + jint human_upper_color = vehicle_info.human_upper_color;
  538 + jint human_lower_color = vehicle_info.human_lower_color;
  539 + jint reverse_driving = vehicle_info.reverse_driving; // 0 正常行驶 1 逆行 -1 未知
  540 + jint phoning = vehicle_info.phoning; // 骑车打电话
  541 + jint cross_line = vehicle_info.cross_line; // 压实线, 1 黄实线 2 白实线 -1 其他
  542 + jint cross_diversion_line = vehicle_info.cross_diversion_line; // 压导流线 1 压了 -1 未压
  543 +
  544 + jobject vehicleInfo = env->NewObject(cls_VehicleInfo, mid_VehicleInfo, vehicleDetectResult, vehicleWinDetectResult, vehicleBodyDetectResult, vehicleColorResult, vehicleRecgResult, vplateResult, vehiclePendantDetResult, vehicleIllegalDetResult, vehicleFeaResult,mtaResult, MannedResult, type, vpt_type, rainshed, truck_manned, motor_manned, human_upper_color, reverse_driving, phoning, cross_line, cross_diversion_line);
534 545
535 env->SetObjectArrayElement(vehicleInfoArray, j, vehicleInfo); 546 env->SetObjectArrayElement(vehicleInfoArray, j, vehicleInfo);
536 } 547 }
@@ -566,12 +577,12 @@ JNIEXPORT void JNICALL Java_com_objecteye_nativeinterface_vehicle_VehicleNativeI @@ -566,12 +577,12 @@ JNIEXPORT void JNICALL Java_com_objecteye_nativeinterface_vehicle_VehicleNativeI
566 577
567 /* 578 /*
568 * Class: com_objecteye_nativeinterface_vehicle_VehicleNativeInterface 579 * Class: com_objecteye_nativeinterface_vehicle_VehicleNativeInterface
569 - * Method: va_get_version 580 + * Method: get_village_pic_version
570 * Signature: ()Ljava/lang/String; 581 * Signature: ()Ljava/lang/String;
571 */ 582 */
572 JNIEXPORT jstring JNICALL Java_com_objecteye_nativeinterface_vehicle_VehicleNativeInterface_getVersion(JNIEnv *env, jobject obj) 583 JNIEXPORT jstring JNICALL Java_com_objecteye_nativeinterface_vehicle_VehicleNativeInterface_getVersion(JNIEnv *env, jobject obj)
573 { 584 {
574 - const char *version = va_get_version(); 585 + const char *version = get_village_pic_version();
575 return env->NewStringUTF(version); 586 return env->NewStringUTF(version);
576 } 587 }
577 588
src/PicAnalysis.cpp
@@ -222,8 +222,8 @@ vector<AnalysisResult> PicAnalysis::analysis_img(vector<sy_img> vec_img){ @@ -222,8 +222,8 @@ vector<AnalysisResult> PicAnalysis::analysis_img(vector<sy_img> vec_img){
222 222
223 sy_rect vehicle_rect = result_info.vehicle_body_detect_res.rect; 223 sy_rect vehicle_rect = result_info.vehicle_body_detect_res.rect;
224 224
225 - if (road_info.direct_mask.cols > 0 && (1 == shot_type || 0 == shot_type)) {  
226 - result_info.reverse_driving = m_road_seg_algorithm.check_reverse_driving(road_info.direct_mask, vehicle_rect, src.width, src.height, shot_type); 225 + if (road_info.vec_direct.size() > 0 && (1 == shot_type || 0 == shot_type)) {
  226 + result_info.reverse_driving = m_road_seg_algorithm.check_reverse_driving(road_info.vec_direct, vehicle_rect, src.width, src.height, shot_type);
227 } 227 }
228 228
229 // 行人 229 // 行人
@@ -250,14 +250,14 @@ vector<AnalysisResult> PicAnalysis::analysis_img(vector<sy_img> vec_img){ @@ -250,14 +250,14 @@ vector<AnalysisResult> PicAnalysis::analysis_img(vector<sy_img> vec_img){
250 // 车尾,判断是否 货车尾部货厢载人 250 // 车尾,判断是否 货车尾部货厢载人
251 if(result_info.vpt_type == 6 || result_info.vpt_type == 7){ 251 if(result_info.vpt_type == 6 || result_info.vpt_type == 7){
252 if(result_info.manned_res.hs_count > 0){ 252 if(result_info.manned_res.hs_count > 0){
253 - result_info.manned = 1; 253 + result_info.truck_manned = 1;
254 } 254 }
255 } 255 }
256 } else { 256 } else {
257 if(result_info.vpt_type == 1 || result_info.vpt_type == 2 || result_info.vpt_type == 3){ 257 if(result_info.vpt_type == 1 || result_info.vpt_type == 2 || result_info.vpt_type == 3){
258 if(result_info.manned_res.hs_count >= 3){ 258 if(result_info.manned_res.hs_count >= 3){
259 // 摩托车、三轮车载人 259 // 摩托车、三轮车载人
260 - result_info.manned = 1; 260 + result_info.motor_manned = 1;
261 } 261 }
262 } 262 }
263 } 263 }
@@ -329,9 +329,10 @@ vector<AnalysisResult> PicAnalysis::analysis_img(vector<sy_img> vec_img){ @@ -329,9 +329,10 @@ vector<AnalysisResult> PicAnalysis::analysis_img(vector<sy_img> vec_img){
329 } 329 }
330 330
331 std::vector<HumanCarResult> vec_hcp_result = m_human_car_algorithm.detect(vec_motor_img); 331 std::vector<HumanCarResult> vec_hcp_result = m_human_car_algorithm.detect(vec_motor_img);
332 - if (vec_hcp_result.size() > 0) {  
333 - if (vec_hcp_result[11] == 0 || vec_hcp_result[11] == 1) {  
334 - result_info.reverse_driving = m_road_seg_algorithm.check_reverse_driving(road_info.direct_mask, vehicle_rect, src.width, src.height, vec_hcp_result[11]); 332 + if (vec_hcp_result.size() > 0 && road_info.vec_direct.size() > 0) {
  333 + int head_or_tail = vec_hcp_result[11].type;
  334 + if (head_or_tail == 0 || head_or_tail == 1) {
  335 + result_info.reverse_driving = m_road_seg_algorithm.check_reverse_driving(road_info.vec_direct, vehicle_rect, src.width, src.height, head_or_tail);
335 } 336 }
336 } 337 }
337 338
src/ai_engine_module/RoadSegAnalysis.cpp
@@ -3,518 +3,6 @@ @@ -3,518 +3,6 @@
3 uint8_t seg_colors[][3] = { {0, 0, 0}, {0, 255, 255}, {128, 255, 0}, {255, 128, 0}, {128, 0, 255}, {255, 0, 128}, {0, 128, 255}, {0, 255, 128}, {128, 255, 255}}; 3 uint8_t seg_colors[][3] = { {0, 0, 0}, {0, 255, 255}, {128, 255, 0}, {255, 128, 0}, {128, 0, 255}, {255, 0, 128}, {0, 128, 255}, {0, 255, 128}, {128, 255, 255}};
4 uint8_t lane_colors[][3] = { {0, 0, 0}, {255, 0, 0}, {0, 255, 0}, {0, 0, 255}, {255, 255, 0}, {255, 0, 255}, {0, 255, 255}, {128, 255, 0}, {255, 128, 0}}; 4 uint8_t lane_colors[][3] = { {0, 0, 0}, {255, 0, 0}, {0, 255, 0}, {0, 0, 255}, {255, 255, 0}, {255, 0, 255}, {0, 255, 255}, {128, 255, 0}, {255, 128, 0}};
5 5
6 -void lanes_process(const rs_lane* lanes, int lane_count, std::vector<std::pair<std::vector<cv::Point>, int>>& combined, float scale_w = 1.0, float scale_h = 1.0) {  
7 - std::vector<std::vector<cv::Point> > lanes_xys;  
8 - std::vector<int> lanes_cls;  
9 - for (int i = 0; i < lane_count; i++) {  
10 - std::vector<cv::Point> xys;  
11 - for (int j = 0; j < lanes[i].num_points; j++) {  
12 - int x = static_cast<int>(lanes[i].points[j].x_ * scale_w);  
13 - int y = static_cast<int>(lanes[i].points[j].y_ * scale_h);  
14 - if (x > 0 && y > 0) {  
15 - xys.emplace_back(x, y);  
16 - }  
17 - }  
18 - if (!xys.empty()) {  
19 - lanes_xys.push_back(xys);  
20 - lanes_cls.push_back(lanes[i].cls);  
21 - }  
22 - }  
23 -  
24 - for (size_t i = 0; i < lanes_xys.size(); ++i) {  
25 - combined.push_back(std::make_pair(lanes_xys[i], lanes_cls[i]));  
26 - }  
27 - if (!combined.empty()) {  
28 - //按车道线起点坐标排序,相应的类别顺序也会变化以保证标签对齐  
29 - std::sort(combined.begin(), combined.end(), [](const std::pair<std::vector<cv::Point>, int>& a, const std::pair<std::vector<cv::Point>, int>& b) {  
30 - return a.first[0].x < b.first[0].x;  
31 - });  
32 - }  
33 -}  
34 -  
35 -cv::Mat mask_to_rgb(cv::Mat img, cv::Mat mask) {  
36 - cv::Mat rgb = img.clone();  
37 - int reg_cls = 9;  
38 - for (int i = 0; i < rgb.rows; i++) {  
39 - for (int j = 0; j < rgb.cols; j++) {  
40 - for (int k = 1; k < reg_cls; k++) {  
41 - if (mask.at<int>(i,j) == k) {  
42 - rgb.at<cv::Vec3b>(i,j)[0] = seg_colors[k][0];  
43 - rgb.at<cv::Vec3b>(i,j)[1] = seg_colors[k][1];  
44 - rgb.at<cv::Vec3b>(i,j)[2] = seg_colors[k][2];  
45 - }  
46 - }  
47 - }  
48 - }  
49 - return rgb;  
50 -}  
51 -  
52 -float contourArea(std::vector<cv::Point> contour, cv::Point2f& center) {  
53 - cv::RotatedRect rect = cv::minAreaRect(contour); // 最小外接矩形 rect[0]中心点 rect[1]宽 高 rect[2]旋转角度  
54 - center = rect.center;  
55 - return cv::contourArea(contour);  
56 -}  
57 -  
58 -int Mask2LanePoints(const cv::Mat& pred, std::vector<std::vector<cv::Point>>&lanes, std::vector<int>& cats) {  
59 - std::vector<int> labels = {9, 10, 11, 12, 13};  
60 - for(auto cat: labels) {  
61 - cv::Mat b_masks, measure_labels, stats, centroids;  
62 - cv::compare(pred, cat, b_masks, cv::CMP_EQ); //将pred元素逐个和cat比较,相同255,不同0  
63 - // cv::threshold(pred, b_masks, 126, 255, cv::THRESH_OTSU); //生成二值图  
64 - // 连通域计算 b_masks:闭操作后的二值图像 measure_labels:和原图一样大的标记图 centroids:nccomps×2的矩阵,表示每个连通域的质心(x, y)  
65 - // stats:nccomps×5的矩阵 表示每个连通区域的外接矩形和面积(x, y, w, h, area),索引0是背景信息  
66 - int nccomps = cv::connectedComponentsWithStats (b_masks, measure_labels, stats, centroids, 4); //8  
67 - for(int cv_measure_id = 1; cv_measure_id < nccomps; cv_measure_id++ ) { //跳过背景信息0  
68 - cv::Mat cv_measure_mask;  
69 - cv::compare(measure_labels, cv_measure_id, cv_measure_mask, cv::CMP_EQ);  
70 - std::vector< std::vector< cv::Point> > contours;  
71 - cv::findContours(cv_measure_mask,contours,cv::noArray(),cv::RETR_TREE,cv::CHAIN_APPROX_SIMPLE);  
72 - std::vector<cv::Point> contours_poly;  
73 - for (int j = 0; j < contours.size();j++) {  
74 - // float area = cv::contourArea(contours[j]); if (area < 60) continue; //30  
75 - float area = cv::contourArea(contours[j]); if (area < 30) continue; //30  
76 - cv::approxPolyDP(cv::Mat(contours[j]), contours_poly, 6, true); //减小epsilon提高拟合精度(需要调试,epsilon过小会使多边形不够简化,单条线变多条)  
77 - if (contours_poly.size() == 1) continue;  
78 - lanes.push_back(contours_poly);  
79 - cats.push_back(cat);  
80 - }  
81 - }  
82 - }  
83 - return 0;  
84 -}  
85 -  
86 -int findMainMaskV2(bool large_resolution, const cv::Mat& solve_masks, const std::vector<int>& labels, std::vector<std::vector<cv::Point>> &poly_masks, std::vector<int> &region_classes, std::vector<std::vector<cv::Point>> &main_masks, cv::Mat& new_mask, cv::Mat& new_mask_forlane) {  
87 - int h = 360, w = 640;  
88 - int seg_num_cls = 8;  
89 - int seg_num_seg = 4;  
90 - int seg_min_region_area = 512; //10  
91 - // mask部分区域  
92 - if (large_resolution) solve_masks(cv::Rect(0, 0, w, int(h * 0.14))) = 0;  
93 - else solve_masks(cv::Rect(0, 0, w, int(h * 0.22))) = 0;  
94 - solve_masks(cv::Rect(0, int(h * 0.95), w, int(h * 0.05))) = 0;  
95 - solve_masks(cv::Rect(0, 0, int(w * 0.02), h)) = 0;  
96 - solve_masks(cv::Rect(int(w * 0.95), 0, int(w * 0.05), h)) = 0;  
97 -  
98 - float hf_w = w*0.5;  
99 - std::vector<std::vector<cv::Point>> all_emerg_contours, all_com_contours, mid_com_contours, mid_zd_contours;  
100 - std::vector<cv::Point> emerg_contours, mid_contours, com_contours, zd_contours;  
101 - float emerg_max_area = 0, max_area = 0, zd_max_area = 0;  
102 -  
103 - for(auto cat: labels) {  
104 - if (cat == 0 || cat > seg_num_seg)  
105 - continue;  
106 -  
107 - // std::cout << cat << std::endl;  
108 - cv::Mat b_masks, measure_labels, stats, centroids;  
109 - cv::Mat n_masks = cv::Mat_<int>(h,w);  
110 - n_masks = cv::Scalar(255);  
111 - cv::compare(solve_masks, cat, b_masks, cv::CMP_EQ); //将solve_masks元素逐个和cat比较,相同255,不同0  
112 - //连通域计算  
113 - int nccomps = cv::connectedComponentsWithStats (b_masks, measure_labels, stats, centroids, 8);  
114 - for(int i = 1; i < nccomps; i++ ) { //跳过背景信息0  
115 - //移除过小的区域,并将对应位置置为0  
116 - if (stats.at<int>(i, cv::CC_STAT_AREA) < seg_min_region_area) {  
117 - cv::Mat comparison_result;  
118 - cv::compare(measure_labels, cv::Scalar(i), comparison_result, cv::CMP_EQ); //相等为255不等为0  
119 - n_masks.setTo(0, comparison_result); // 将comparison_result中非零区域置为0  
120 - cv::bitwise_and(solve_masks,n_masks,solve_masks);  
121 - continue;  
122 - }  
123 -  
124 - double centr_x = centroids.at<double>(i, 0);  
125 - double centr_y = centroids.at<double>(i, 1);  
126 -  
127 - int region_class = cat;  
128 - cv::Mat region_mask;  
129 - cv::bitwise_and(measure_labels,n_masks,measure_labels);/////  
130 - cv::compare(measure_labels, i, region_mask, cv::CMP_EQ);  
131 -  
132 - // 闭运算,先膨胀再腐蚀,去除较暗部分  
133 - cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(17, 5));  
134 - cv::morphologyEx(region_mask, region_mask, cv::MORPH_CLOSE, kernel);  
135 -  
136 - std::vector< std::vector< cv::Point> > contours;  
137 - cv::findContours(region_mask,contours,cv::noArray(),cv::RETR_TREE,cv::CHAIN_APPROX_SIMPLE);  
138 - std::vector<cv::Point> contours_poly;  
139 -  
140 - // 应急车道  
141 - if(region_class == 2) {  
142 - for (auto contour : contours) {  
143 - cv::Point2f center;  
144 - float area_ = contourArea(contour, center);  
145 - if (area_ > emerg_max_area) {  
146 - emerg_max_area = area_;  
147 - emerg_contours = contour;  
148 - }  
149 - all_emerg_contours.push_back(contour);  
150 - }  
151 - }  
152 -  
153 - // 普通行车道  
154 - if(region_class == 1) {  
155 - for (auto contour : contours) {  
156 - cv::Point2f center;  
157 - float area_ = contourArea(contour, center);  
158 - if (area_ > max_area) {  
159 - max_area = area_;  
160 - com_contours = contour;  
161 - }  
162 - // 取中点所在的连通域  
163 - cv::Point2f point(int(w*0.5),int(h*0.95)-1);  
164 - double distance = cv::pointPolygonTest(contour, point, false);  
165 - if (distance >= 0) {  
166 - mid_contours = contour;  
167 - hf_w = center.x;  
168 - continue;  
169 - }  
170 - if (abs(center.x - hf_w) < 90) // 取中点所在区域左右90像素内的连通域 230307  
171 - mid_com_contours.push_back(contour);  
172 - }  
173 - }  
174 -  
175 - // 导流线  
176 - if(region_class == 3) {  
177 - for (auto contour : contours) {  
178 - cv::Point2f center;  
179 - float area_ = contourArea(contour, center);  
180 - if (area_ > zd_max_area) {  
181 - zd_max_area = area_;  
182 - zd_contours = contour;  
183 - }  
184 - // if (abs(center.x - w*0.5) < 200) // 取中点左右200像素内的连通域  
185 - if (abs(center.x - w*0.5) < 250) // 取中点左右250像素内的连通域  
186 - mid_zd_contours.push_back(contour);  
187 - }  
188 - }  
189 -  
190 - // 拟合各行驶区域  
191 - for (int j = 0; j < contours.size();j++) {  
192 - cv::approxPolyDP(cv::Mat(contours[j]), contours_poly, 10, true);  
193 - if (contours_poly.size() <= 2) continue;  
194 - poly_masks.push_back(contours_poly);  
195 - region_classes.push_back(cat);  
196 - }  
197 - }  
198 - }  
199 -  
200 - // cv::Mat new_mask(h, w, CV_8UC3, cv::Scalar(0,0,0));  
201 - if (!mid_contours.empty()) {  
202 - // cv::fillConvexPoly(new_mask, mid_contours, cv::Scalar(255,255,255)); //填充255  
203 - cv::fillConvexPoly(new_mask, mid_contours, cv::Scalar(255)); //填充255  
204 - cv::fillConvexPoly(new_mask_forlane, mid_contours, cv::Scalar(255)); //填充255  
205 - std::vector<cv::Point> contours_poly;  
206 - cv::approxPolyDP(cv::Mat(mid_contours), contours_poly, 10, true);  
207 - if (contours_poly.size() > 2) main_masks.push_back(contours_poly);  
208 - all_com_contours.push_back(mid_contours);  
209 - }  
210 - else {  
211 - // cv::fillConvexPoly(new_mask, com_contours, cv::Scalar(255,255,255)); //填充255  
212 - cv::fillConvexPoly(new_mask, com_contours, cv::Scalar(255)); //填充255  
213 - cv::fillConvexPoly(new_mask_forlane, com_contours, cv::Scalar(255)); //填充255  
214 - std::vector<cv::Point> contours_poly;  
215 - cv::approxPolyDP(cv::Mat(com_contours), contours_poly, 10, true);  
216 - if (contours_poly.size() > 2) main_masks.push_back(contours_poly);  
217 - all_com_contours.push_back(com_contours);  
218 - }  
219 -  
220 - for (auto contour_ : mid_com_contours) {  
221 - // cv::fillConvexPoly(new_mask, contour_, cv::Scalar(255,255,255)); //填充255  
222 - cv::fillConvexPoly(new_mask, contour_, cv::Scalar(255)); //填充255  
223 - cv::fillConvexPoly(new_mask_forlane, contour_, cv::Scalar(255)); //填充255  
224 - std::vector<cv::Point> contours_poly;  
225 - cv::approxPolyDP(cv::Mat(contour_), contours_poly, 10, true);  
226 - if (contours_poly.size() > 2) main_masks.push_back(contours_poly);  
227 - all_com_contours.push_back(contour_);  
228 - }  
229 -  
230 - if (!emerg_contours.empty() && !all_emerg_contours.empty()) {  
231 - if (all_emerg_contours.size() == 1)  
232 - // cv::fillConvexPoly(new_mask, emerg_contours, cv::Scalar(255,255,255));  
233 - cv::fillConvexPoly(new_mask, emerg_contours, cv::Scalar(255)); //填充255  
234 - else {  
235 - float sum_centerx = 0, sum_centery = 0;  
236 - float length_emerg_com = 9999999;  
237 - // 计算选中行车道的平均中心点  
238 - for (auto contour_ : all_com_contours) {  
239 - cv::Point2f center;  
240 - float area_ = contourArea(contour_, center);  
241 - sum_centerx += center.x;  
242 - sum_centery += center.y;  
243 - }  
244 - float ave_centerx = sum_centerx / all_com_contours.size();  
245 - float ave_centery = sum_centery / all_com_contours.size();  
246 - // 选择距离最近的应急车道且面积不小于最大应急车道的一半  
247 - for (auto econtour_ : all_emerg_contours) {  
248 - cv::Point2f center;  
249 - float area_ = contourArea(econtour_, center);  
250 - float tmp_length = sqrt(pow((ave_centerx-center.x),2.0) + pow((ave_centery-center.y),2.0));  
251 - if (tmp_length < length_emerg_com and area_ > 0.7*emerg_max_area) {  
252 - length_emerg_com = tmp_length;  
253 - emerg_contours = econtour_;  
254 - }  
255 - }  
256 - // cv::fillConvexPoly(new_mask, emerg_contours, cv::Scalar(255,255,255));  
257 - cv::fillConvexPoly(new_mask, emerg_contours, cv::Scalar(255)); //填充255  
258 - }  
259 - }  
260 -  
261 - if (!mid_zd_contours.empty()) {  
262 - for (auto contour_ : mid_zd_contours)  
263 - // cv::fillConvexPoly(new_mask, contour_, cv::Scalar(255,255,255)); //填充255  
264 - cv::fillConvexPoly(new_mask, contour_, cv::Scalar(255)); //填充255  
265 - }  
266 -  
267 - // 膨胀腐蚀,去除行车道和应急车道间的空洞  
268 - cv::Mat kernel_ = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(17, 5));  
269 - cv::morphologyEx(new_mask, new_mask, cv::MORPH_CLOSE, kernel_);  
270 - cv::morphologyEx(new_mask_forlane, new_mask_forlane, cv::MORPH_CLOSE, kernel_);  
271 -  
272 - return 0;  
273 -}  
274 -  
275 -  
276 -cv::Mat seg_post_process(bool large_resolution, unsigned char *seg_array, std::vector<std::pair<std::vector<cv::Point>, int>> combined, std::vector<std::vector<cv::Point>> &poly_masks, std::vector<int> &region_classes, std::vector<std::vector<cv::Point>> &lanes, std::vector<int> &cats, std::map<double, int> &x_sort, cv::Mat &background_mask) {  
277 - std::vector<int> pred_cls;  
278 - int h = 360, w = 640;  
279 - cv::Mat lanes_masks = cv::Mat_<int>(h,w); //正常分割结果  
280 - cv::Mat mask_rmlane = cv::Mat_<int>(h,w); //车道线区域置为背景  
281 - cv::Mat solve_masks = cv::Mat_<int>(h,w); //计算主行驶区域用(虚线及减速标线归入行车道)  
282 - int step_size = h*w;  
283 - int seg_min_region_area = 512; //1024  
284 -  
285 - for (int i = 0; i < h; ++i) {  
286 - for (int j = 0; j < w; ++j) {  
287 - int max_cls = seg_array[(i * w + j)];  
288 - lanes_masks.ptr<int>(i)[j] = max_cls;  
289 - pred_cls.push_back(max_cls);  
290 - mask_rmlane.ptr<int>(i)[j] = max_cls;  
291 - solve_masks.ptr<int>(i)[j] = max_cls;  
292 - }  
293 - }  
294 -  
295 - for (const auto& lane_info : combined) {  
296 - const auto& xys = lane_info.first;  
297 - int cls = lane_info.second;  
298 - if (cls == 1) cls = 9; /*黄实线*/ if (cls == 2) cls = 10; /*白实线*/  
299 - if (cls == 3) cls = 11; /*虚线*/ if (cls == 4) cls = 12; /*黄虚线*/  
300 - if (cls == 5) cls = 13; /*车道中线*/  
301 - for (size_t i = 1; i < xys.size(); ++i) {  
302 - cv::line(lanes_masks, xys[i - 1], xys[i], cls, 4); //绘制车道线用于求连通域  
303 - if (cls == 11 || cls == 12) cls = 1; //求主行驶区域时将虚线归入行车道  
304 - cv::line(solve_masks, xys[i - 1], xys[i], cls, 4);  
305 -  
306 - }  
307 - }  
308 -  
309 - // 求背景区域--mask车道区域,场景变化用  
310 - cv::compare(lanes_masks, 0, background_mask, cv::CMP_EQ); //将lanes_masks元素逐个和0比较,相同255,不同0  
311 -#if 0  
312 - //--mask远处区域------------------------------------------------  
313 - cv::Mat mask_black = mask_rmlane.clone();  
314 - if (large_resolution) mask_black(cv::Rect(0, 0, w, int(h * 0.14))) = 0;  
315 - else mask_black(cv::Rect(0, 0, w, int(h * 0.22))) = 0;  
316 - mask_black(cv::Rect(0, int(h * 0.95), w, int(h * 0.05))) = 0;  
317 - mask_black(cv::Rect(0, 0, int(w * 0.02), h)) = 0;  
318 - mask_black(cv::Rect(int(w * 0.95), 0, int(w * 0.05), h)) = 0;  
319 - mask_rmlane = mask_black;  
320 - //-------------------------------------------------------------------------  
321 -#endif  
322 - //2.去重获取预测到的类别  
323 - std::vector<int> labels(pred_cls);  
324 - std::sort(labels.begin(),labels.end());  
325 - labels.erase(std::unique(labels.begin(),labels.end()),labels.end());  
326 -  
327 - //4.求车道线区域  
328 - int flag = Mask2LanePoints(lanes_masks, lanes, cats); ///////////////////////// 车道线如何与mask结合  
329 -  
330 - //5.求道路区域  
331 - int count = 0;  
332 - for(auto cat: labels) {  
333 - // std::cout << cat << std::endl;  
334 - cv::Mat b_masks, measure_labels, stats, centroids;  
335 - cv::Mat n_masks = cv::Mat_<int>(h,w);  
336 - n_masks = cv::Scalar(255);  
337 - cv::compare(mask_rmlane, cat, b_masks, cv::CMP_EQ); //将mask_rmlane元素逐个和cat比较,相同255,不同0  
338 - //连通域计算  
339 - int nccomps = cv::connectedComponentsWithStats (b_masks, measure_labels, stats, centroids, 8);  
340 - for(int i = 1; i < nccomps; i++ ) { //跳过背景信息0  
341 - //移除过小的区域,并将对应位置置为0  
342 - if (stats.at<int>(i, cv::CC_STAT_AREA) < seg_min_region_area) {  
343 - cv::Mat comparison_result;  
344 - cv::compare(measure_labels, cv::Scalar(i), comparison_result, cv::CMP_EQ); //相等为255不等为0  
345 - n_masks.setTo(0, comparison_result); // 将comparison_result中非零区域置为0  
346 -  
347 - cv::bitwise_and(mask_rmlane,n_masks,mask_rmlane);  
348 - continue;  
349 - }  
350 -  
351 - double centr_x = centroids.at<double>(i, 0);  
352 - double centr_y = centroids.at<double>(i, 1);  
353 -  
354 - int region_class = cat;  
355 - // printf("region_class: %d\n", region_class);  
356 - cv::Mat region_mask;  
357 - cv::bitwise_and(measure_labels,n_masks,measure_labels);/////  
358 - cv::compare(measure_labels, i, region_mask, cv::CMP_EQ);  
359 -  
360 - std::vector< std::vector< cv::Point> > contours;  
361 - cv::findContours(region_mask,contours,cv::noArray(),cv::RETR_TREE,cv::CHAIN_APPROX_SIMPLE);  
362 - std::vector<cv::Point> contours_poly;  
363 - for (int j = 0; j < contours.size();j++) {  
364 - cv::approxPolyDP(cv::Mat(contours[j]), contours_poly, 10, true);  
365 - if (contours_poly.size() <= 2) continue;  
366 - poly_masks.push_back(contours_poly);  
367 - region_classes.push_back(cat);  
368 - if (x_sort.count(centr_x)) centr_x += 0.0001;  
369 - x_sort.insert(std::make_pair(centr_x, count));  
370 - ++ count;  
371 - // for (auto iter: contours_poly) {  
372 - // std::cout << "contour " << iter << " " << cat << std::endl;  
373 - // }  
374 -  
375 - }  
376 - }  
377 - }  
378 -  
379 -#if 0  
380 - //6.draw lanes  
381 - for (int i = 0; i < lanes.size(); ++i) {  
382 - int thickness = 4;  
383 - for (int j = 0; j < lanes[i].size()-1; ++j) {  
384 - cv::line(mask_rmlane, lanes[i][j], lanes[i][j+1], cats[i], thickness);  
385 - // std::cout << lanes[i][j] << " " << lanes[i][j+1] << " " << cats[i] << std::endl;  
386 - }  
387 - }  
388 -#endif  
389 - return mask_rmlane;  
390 -}  
391 -  
392 -  
393 -  
394 -cv::Mat direct_post_process(bool large_resolution, unsigned char *direct_array, std::vector<std::vector<cv::Point>> &poly_masks, std::vector<int> &region_classes) {  
395 - std::vector<int> pred_cls;  
396 - int h = 360, w = 640, step_size = h*w, seg_min_region_area = 512;  
397 - cv::Mat mask_rmlane = cv::Mat_<int>(h,w); //车道线区域置为背景  
398 - for (int i = 0; i < h; ++i) {  
399 - for (int j = 0; j < w; ++j) {  
400 - int max_cls = direct_array[(i * w + j)];  
401 - pred_cls.push_back(max_cls);  
402 - mask_rmlane.ptr<int>(i)[j] = max_cls;  
403 - }  
404 - }  
405 -  
406 -#if 1 /*mask远处区域*/  
407 - cv::Mat mask_black = mask_rmlane.clone();  
408 - if (large_resolution) mask_black(cv::Rect(0, 0, w, int(h * 0.14))) = 0;  
409 - else mask_black(cv::Rect(0, 0, w, int(h * 0.22))) = 0;  
410 - mask_black(cv::Rect(0, int(h * 0.95), w, int(h * 0.05))) = 0;  
411 - mask_black(cv::Rect(0, 0, int(w * 0.02), h)) = 0;  
412 - mask_black(cv::Rect(int(w * 0.95), 0, int(w * 0.05), h)) = 0;  
413 - mask_rmlane = mask_black;  
414 -#endif  
415 - //去重获取预测到的类别  
416 - std::vector<int> labels(pred_cls);  
417 - std::sort(labels.begin(),labels.end());  
418 - labels.erase(std::unique(labels.begin(),labels.end()),labels.end());  
419 -  
420 - //求道路区域  
421 - for(auto cat: labels) {  
422 - cv::Mat b_masks, measure_labels, stats, centroids;  
423 - cv::Mat n_masks = cv::Mat_<int>(h,w); n_masks = cv::Scalar(255);  
424 - cv::compare(mask_rmlane, cat, b_masks, cv::CMP_EQ); //将mask_rmlane元素逐个和cat比较,相同255,不同0  
425 - //连通域计算  
426 - int nccomps = cv::connectedComponentsWithStats (b_masks, measure_labels, stats, centroids, 8);  
427 - for(int i = 1; i < nccomps; i++ ) { //跳过背景信息0  
428 - if (stats.at<int>(i, cv::CC_STAT_AREA) < seg_min_region_area) { //移除过小的区域,并将对应位置置为0  
429 - cv::Mat comparison_result;  
430 - cv::compare(measure_labels, cv::Scalar(i), comparison_result, cv::CMP_EQ); //相等为255不等为0  
431 - n_masks.setTo(0, comparison_result); // 将comparison_result中非零区域置为0  
432 - cv::bitwise_and(mask_rmlane,n_masks,mask_rmlane);  
433 - continue;  
434 - }  
435 -  
436 - cv::Mat region_mask;  
437 - cv::bitwise_and(measure_labels,n_masks,measure_labels);/////  
438 - cv::compare(measure_labels, i, region_mask, cv::CMP_EQ);  
439 -  
440 - std::vector<std::vector<cv::Point>> contours;  
441 - cv::findContours(region_mask,contours,cv::noArray(),cv::RETR_TREE,cv::CHAIN_APPROX_SIMPLE);  
442 - std::vector<cv::Point> contours_poly;  
443 - for (int j = 0; j < contours.size();j++) {  
444 - cv::approxPolyDP(cv::Mat(contours[j]), contours_poly, 10, true);  
445 - if (contours_poly.size() <= 2) continue;  
446 - poly_masks.push_back(contours_poly);  
447 - region_classes.push_back(cat);  
448 - }  
449 - }  
450 - }  
451 - return mask_rmlane;  
452 -}  
453 -  
454 -  
455 -// 合并来去区域  
456 -cv::Mat merge_direct_process(bool large_resolution, unsigned char *direct_array, std::vector<std::vector<cv::Point>> &poly_masks, std::vector<int> &region_classes) {  
457 - std::vector<int> pred_cls;  
458 - int h = 360, w = 640, step_size = h*w, seg_min_region_area = 512;  
459 - cv::Mat mask_rmlane = cv::Mat_<int>(h,w); //车道线区域置为背景  
460 - for (int i = 0; i < h; ++i) {  
461 - for (int j = 0; j < w; ++j) {  
462 - int max_cls = direct_array[(i * w + j)];  
463 - if (max_cls == 1 || max_cls == 2) max_cls = 5; // 来去区域合并的类别为5  
464 - if (max_cls == 3 || max_cls == 4) max_cls = 6; // 近远区域合并的类别为6  
465 - pred_cls.push_back(max_cls);  
466 - mask_rmlane.ptr<int>(i)[j] = max_cls;  
467 - }  
468 - }  
469 -  
470 -#if 0 /*mask远处区域*/  
471 - cv::Mat mask_black = mask_rmlane.clone();  
472 - if (large_resolution) mask_black(cv::Rect(0, 0, w, int(h * 0.14))) = 0;  
473 - else mask_black(cv::Rect(0, 0, w, int(h * 0.22))) = 0;  
474 - mask_black(cv::Rect(0, int(h * 0.95), w, int(h * 0.05))) = 0;  
475 - mask_black(cv::Rect(0, 0, int(w * 0.02), h)) = 0;  
476 - mask_black(cv::Rect(int(w * 0.95), 0, int(w * 0.05), h)) = 0;  
477 - mask_rmlane = mask_black;  
478 -#endif  
479 - //去重获取预测到的类别  
480 - std::vector<int> labels(pred_cls);  
481 - std::sort(labels.begin(),labels.end());  
482 - labels.erase(std::unique(labels.begin(),labels.end()),labels.end());  
483 -  
484 - //求道路区域  
485 - for(auto cat: labels) {  
486 - cv::Mat b_masks, measure_labels, stats, centroids;  
487 - cv::Mat n_masks = cv::Mat_<int>(h,w); n_masks = cv::Scalar(255);  
488 - cv::compare(mask_rmlane, cat, b_masks, cv::CMP_EQ); //将mask_rmlane元素逐个和cat比较,相同255,不同0  
489 - //连通域计算  
490 - int nccomps = cv::connectedComponentsWithStats (b_masks, measure_labels, stats, centroids, 8);  
491 - for(int i = 1; i < nccomps; i++ ) { //跳过背景信息0  
492 - if (stats.at<int>(i, cv::CC_STAT_AREA) < seg_min_region_area) { //移除过小的区域,并将对应位置置为0  
493 - cv::Mat comparison_result;  
494 - cv::compare(measure_labels, cv::Scalar(i), comparison_result, cv::CMP_EQ); //相等为255不等为0  
495 - n_masks.setTo(0, comparison_result); // 将comparison_result中非零区域置为0  
496 - cv::bitwise_and(mask_rmlane,n_masks,mask_rmlane);  
497 - continue;  
498 - }  
499 -  
500 - cv::Mat region_mask;  
501 - cv::bitwise_and(measure_labels,n_masks,measure_labels);/////  
502 - cv::compare(measure_labels, i, region_mask, cv::CMP_EQ);  
503 -  
504 - std::vector<std::vector<cv::Point>> contours;  
505 - cv::findContours(region_mask,contours,cv::noArray(),cv::RETR_TREE,cv::CHAIN_APPROX_SIMPLE);  
506 - std::vector<cv::Point> contours_poly;  
507 - for (int j = 0; j < contours.size();j++) {  
508 - cv::approxPolyDP(cv::Mat(contours[j]), contours_poly, 10, true);  
509 - if (contours_poly.size() <= 2) continue;  
510 - poly_masks.push_back(contours_poly);  
511 - region_classes.push_back(cat);  
512 - }  
513 - }  
514 - }  
515 - return mask_rmlane;  
516 -}  
517 -  
518 RoadSegAnalysis::RoadSegAnalysis(/* args */) 6 RoadSegAnalysis::RoadSegAnalysis(/* args */)
519 { 7 {
520 } 8 }
@@ -573,34 +61,91 @@ std::vector&lt;RoadInfo&gt; RoadSegAnalysis::detect(vector&lt;sy_img&gt; vec_img){ @@ -573,34 +61,91 @@ std::vector&lt;RoadInfo&gt; RoadSegAnalysis::detect(vector&lt;sy_img&gt; vec_img){
573 61
574 for (int b = 0; b < batchsize; b++) { 62 for (int b = 0; b < batchsize; b++) {
575 auto one_result = results[b]; 63 auto one_result = results[b];
576 - RoadInfo one_road;  
577 - for (size_t i = 0; i < one_result.lane_count; i++)  
578 - {  
579 - auto one_lane = one_result.reg_array[i];  
580 - LineInfo info;  
581 - for (size_t j = 0; j < one_lane.num_points; j++)  
582 - {  
583 - info.vec_pt.push_back(one_lane.points[j]);  
584 - }  
585 - info.line_type = one_lane.cls;  
586 - one_road.vec_line.push_back(info);  
587 - } 64 + RoadInfo one_road = parse_road(one_result, vec_img[b]);
  65 + one_road.vec_direct = parse_direct(one_result, vec_img[b]);
  66 + vec_road.push_back(one_road);
  67 + }
  68 +
  69 + } while (0);
  70 +
  71 + for (int b = 0; b < batchsize; b++) {
  72 + delete[] results[b].seg_array;
  73 + results[b].seg_array = NULL;
  74 + delete[] results[b].direct_seg;
  75 + results[b].direct_seg = NULL;
  76 + }
  77 +
  78 + return vec_road;
  79 +}
  80 +
  81 +RoadInfo RoadSegAnalysis::parse_road(rs_result one_result, sy_img src)
  82 +{
  83 + RoadInfo one_road;
  84 +
  85 + std::vector<std::pair<std::vector<cv::Point>, int>> combined;
  86 + lanes_process(one_result.reg_array, one_result.lane_count, combined);
  87 + std::vector<std::vector<cv::Point>> poly_masks, lanes;
  88 + std::vector<int> region_classes, cats;
  89 + std::map<double, int> x_sort;
  90 + bool large_resolution = false;
  91 + if (src.w_ > 1920) large_resolution = true;
  92 +
  93 + cv::Mat seg_output = seg_post_process(large_resolution, one_result.seg_array, combined, poly_masks, region_classes, lanes, cats, x_sort); //m_masks:mask前的结果 poly_masks后的结果
588 94
589 - one_road.vec_road = parse_seg(one_result, vec_img[b]);  
590 - one_road.direct_mask = parse_direct(one_result, vec_img[b]); 95 + for (int i = 0; i < lanes.size(); ++i) {
  96 + std::vector<cv::Point> points = lanes[i];
  97 + LineInfo info;
  98 + for (size_t j = 0; j < points.size(); j++)
  99 + {
  100 + sy_point pt;
  101 + pt.x_ = points[j].x;
  102 + pt.y_ = points[j].y;
591 103
592 - post_direct(one_result, vec_img[b]);  
593 -  
594 - vec_road.push_back(one_road); 104 + info.vec_pt.push_back(pt);
595 } 105 }
  106 + info.line_type = cats[i];
  107 + one_road.vec_line.push_back(info);
  108 + }
  109 +
  110 + for (int i = 0; i < poly_masks.size(); ++i) {
  111 + std::vector<cv::Point> points = poly_masks[i];
  112 + SegInfo seg_info;
  113 + for (int j = 0; j < points.size(); ++j) {
  114 + sy_point pt;
  115 + pt.x_ = points[j].x;
  116 + pt.y_ = points[j].y;
596 117
597 - } while (0); 118 + seg_info.vec_pt.push_back(pt);
  119 + }
  120 + seg_info.seg_type = region_classes[i];
  121 + one_road.vec_road.push_back(seg_info);
  122 + }
  123 +}
598 124
599 - for (int b = 0; b < batchsize; b++) {  
600 - delete[] results[b].seg_array;  
601 - results[b].seg_array = NULL;  
602 - delete[] results[b].direct_seg;  
603 - results[b].direct_seg = NULL; 125 +std::vector<SegInfo> RoadSegAnalysis::parse_direct(rs_result one_result, sy_img src) {
  126 + std::vector<std::pair<std::vector<cv::Point>, int>> combined;
  127 + lanes_process(one_result.reg_array, one_result.lane_count, combined);
  128 + std::vector<std::vector<cv::Point>> poly_masks, lanes;
  129 + std::vector<int> region_classes, cats;
  130 + std::map<double, int> x_sort;
  131 + bool large_resolution = false;
  132 + if (src.w_ > 1920) large_resolution = true;
  133 +
  134 + cv::Mat seg_output = seg_post_process(large_resolution, one_result.direct_seg, combined, poly_masks, region_classes, lanes, cats, x_sort); //m_masks:mask前的结果 poly_masks后的结果
  135 +
  136 + std::vector<SegInfo> vec_road;
  137 + for (int i = 0; i < poly_masks.size(); ++i) {
  138 + std::vector<cv::Point> points = poly_masks[i];
  139 + SegInfo seg_info;
  140 + for (int j = 0; j < points.size(); ++j) {
  141 + sy_point pt;
  142 + pt.x_ = points[j].x;
  143 + pt.y_ = points[j].y;
  144 +
  145 + seg_info.vec_pt.push_back(pt);
  146 + }
  147 + seg_info.seg_type = region_classes[i];
  148 + vec_road.push_back(seg_info);
604 } 149 }
605 150
606 return vec_road; 151 return vec_road;
@@ -622,95 +167,81 @@ int RoadSegAnalysis::release() { @@ -622,95 +167,81 @@ int RoadSegAnalysis::release() {
622 return SY_SUCCESS; 167 return SY_SUCCESS;
623 } 168 }
624 169
625 -std::vector<SegInfo> RoadSegAnalysis::parse_seg(rs_result one_result, sy_img src) {  
626 - int w = 640;  
627 - int h = 360;  
628 - float alpha = 0.75;  
629 - cv::Mat overlayed_img(cv::Size(w,h), CV_8UC3, cv::Scalar(0, 0, 0));  
630 - // 将车道线标签转换为彩色图像  
631 - for (int i = 0; i < h; ++i) {  
632 - for (int j = 0; j < w; ++j) {  
633 - int idx = one_result.seg_array[(i * w + j)];  
634 - overlayed_img.at<cv::Vec3b>(i, j)[0] = seg_colors[idx][0]; // R通道;  
635 - overlayed_img.at<cv::Vec3b>(i, j)[1] = seg_colors[idx][1]; // G通道  
636 - overlayed_img.at<cv::Vec3b>(i, j)[2] = seg_colors[idx][2]; // B通道  
637 - }  
638 - } 170 +// head_or_tail 0:车头 1:车尾
  171 +int RoadSegAnalysis::check_reverse_driving(std::vector<SegInfo>& vec_direct, sy_rect src_rc, int src_width, int src_height, int head_or_tail) {
639 172
640 - cv::resize(overlayed_img, overlayed_img, cv::Size(src.w_,src.h_), 0, 0, cv::INTER_LINEAR);  
641 - // 将原始图像和彩色车道线图进行混合  
642 - // cv::addWeighted(cvImg, alpha, overlayed_img, 1 - alpha, 0, overlayed_img); 173 + float scale_w = 640.0 / src_width;
  174 + float scale_h = 360.0 / src_height;
643 175
644 - float scale_w = src.w_ / 640.0;  
645 - float scale_h = src.h_ / 360.0;  
646 - std::vector<std::pair<std::vector<cv::Point>, int>> combined;  
647 - lanes_process(one_result.reg_array, one_result.lane_count, combined, scale_w, scale_h); 176 + sy_rect rc;
  177 + rc.left_ = src_rc.left_ * scale_w;
  178 + rc.width_ = src_rc.width_ * scale_w;
  179 + rc.top_ = src_rc.top_ * scale_h;
  180 + rc.height_ = src_rc.height_ * scale_h;
648 181
649 - std::vector<SegInfo> vec_seg;  
650 - for (const auto& lane_info : combined) {  
651 - const auto& xys = lane_info.first;  
652 - int cls = lane_info.second;  
653 - SegInfo info;  
654 - info.seg_type = cls;  
655 - // cv::Scalar color(lane_colors[cls][0],lane_colors[cls][1],lane_colors[cls][2]);  
656 - for (size_t i = 0; i < xys.size(); ++i) {  
657 - // cv::line(overlayed_img, xys[i - 1], xys[i], color, 4);  
658 - sy_point pt;  
659 - pt.x_ = xys[i].x;  
660 - pt.y_ = xys[i].y;  
661 - info.vec_pt.push_back(pt); 182 + std::vector<cv::Point> polygon_pts;
  183 + cv::Point pt_lt;
  184 + pt_lt.x = rc.left_;
  185 + pt_lt.y = rc.top_;
  186 + polygon_pts.push_back(pt_lt);
  187 + cv::Point pt_rt;
  188 + pt_rt.x = rc.left_ + rc.width_;
  189 + pt_rt.y = rc.top_;
  190 + polygon_pts.push_back(pt_rt);
  191 + cv::Point pt_rb;
  192 + pt_rb.x = rc.left_ + rc.width_;
  193 + pt_rb.y = rc.top_ + rc.height_;
  194 + polygon_pts.push_back(pt_rb);
  195 + cv::Point pt_lb;
  196 + pt_lb.x = rc.left_;
  197 + pt_lb.y = rc.top_ + rc.height_;
  198 + polygon_pts.push_back(pt_lb);
  199 +
  200 + int coming_count = 0;
  201 + int leaving_count = 0;
  202 + for (size_t i = 0; i < vec_direct.size(); i++) {
  203 + SegInfo& region = vec_direct[i];
  204 + if (region.seg_type == 1) {
  205 + std::vector<cv::Point> vec_pt;
  206 + for (size_t j = 0; j < region.vec_pt.size(); j++) {
  207 + double dist = pointPolygonTest(polygon_pts, cv::Point2f(region.vec_pt[j].x_, region.vec_pt[j].y_), false);
  208 + if (dist > 0) {
  209 + coming_count ++;
  210 + }
  211 + }
  212 + } else if (region.seg_type == 2) {
  213 + std::vector<cv::Point> vec_pt;
  214 + for (size_t j = 0; j < region.vec_pt.size(); j++) {
  215 + double dist = pointPolygonTest(polygon_pts, cv::Point2f(region.vec_pt[j].x_, region.vec_pt[j].y_), false);
  216 + if (dist > 0) {
  217 + leaving_count ++;
  218 + }
  219 + }
662 } 220 }
663 - vec_seg.push_back(info);  
664 } 221 }
665 222
666 - return vec_seg;  
667 -}  
668 -  
669 -cv::Mat RoadSegAnalysis::parse_direct(rs_result one_result, sy_img src){  
670 - int src_width = src.w_;  
671 -  
672 - std::vector<std::pair<std::vector<cv::Point>, int>> combined;  
673 - lanes_process(one_result.reg_array, one_result.lane_count, combined);  
674 - std::vector<std::vector<cv::Point>> poly_masks, lanes, direct_masks, merge_masks;  
675 - std::vector<int> region_classes, cats, direct_classes, merge_classes;  
676 - cv::Mat background_mask;  
677 - std::map<double, int> x_sort;  
678 - bool large_resolution = false;  
679 - if (src_width > 1920) large_resolution = true;  
680 - cv::Mat seg_output = seg_post_process(large_resolution, one_result.seg_array, combined, poly_masks, region_classes, lanes, cats, x_sort, background_mask); //m_masks:mask前的结果 poly_masks后的结果  
681 - cv::Mat direct_output = direct_post_process(large_resolution, one_result.direct_seg, direct_masks, direct_classes);  
682 -  
683 -  
684 - // std::vector<std::vector<cv::Point>> direct_masks;  
685 - // std::vector<int> direct_classes;  
686 - // bool large_resolution = false;  
687 - // if (src_width > 1920) large_resolution = true;  
688 - // cv::Mat direct_output = direct_post_process(large_resolution, one_result.direct_seg, direct_masks, direct_classes);  
689 -  
690 - // cv::Mat image(cv::Size(640, 360), CV_8UC3, cv::Scalar(0, 0, 0));  
691 - // cv::Mat merge_image = mask_to_rgb(image, direct_output);  
692 - // cv::imwrite("direct.jpg", merge_image);  
693 -  
694 - int direct = direct_output.at<int>(455, 146); 223 + int direct = 0;
  224 + if(coming_count > 0 && leaving_count > 0) {
  225 + if (coming_count > leaving_count) {
  226 + direct = 1;
  227 + } else {
  228 + direct = 2;
  229 + }
  230 + } else if(coming_count > 0 && leaving_count <= 0) {
  231 + direct = 1;
  232 + } else if(coming_count <= 0 && leaving_count > 0) {
  233 + direct = 2;
  234 + }
695 235
696 - return direct_output;  
697 -}  
698 236
699 -// head_or_tail 0:车头 1:车尾  
700 -int RoadSegAnalysis::check_reverse_driving(cv::Mat direct_mask, sy_rect rc, int src_width, int src_height, int head_or_tail) {  
701 - // cv::Mat image(cv::Size(640, 360), CV_8UC3, cv::Scalar(0, 0, 0));  
702 - // cv::Mat merge_image = mask_to_rgb(image, direct_mask);  
703 - // cv::imwrite("direct_mask.jpg", merge_image); 237 + // int center_x = (rc.left_ + rc.width_ / 2) * scale_w;
  238 + // int center_y = (rc.top_ + rc.height_ / 2) * scale_h;
  239 + // if(center_x < 0 ||center_x >= direct_mask.cols || center_y < 0 || center_y >= direct_mask.rows){
  240 + // return -1;
  241 + // }
704 242
705 - float scale_w = 640.0 / src_width;  
706 - float scale_h = 360.0 / src_height;  
707 - int center_x = (rc.left_ + rc.width_ / 2) * scale_w;  
708 - int center_y = (rc.top_ + rc.height_ / 2) * scale_h;  
709 - if(center_x < 0 ||center_x >= direct_mask.cols || center_y < 0 || center_y >= direct_mask.rows){  
710 - return -1;  
711 - }  
712 // '来': 1, '去': 2, '近': 3, '远': 4 243 // '来': 1, '去': 2, '近': 3, '远': 4
713 - int direct = direct_mask.at<int>(center_x, center_y); 244 + // int direct = direct_mask.at<int>(center_x, center_y);
714 if (direct == 1 && head_or_tail == 0) { 245 if (direct == 1 && head_or_tail == 0) {
715 // 来车道,车头,正常行驶 246 // 来车道,车头,正常行驶
716 return 0; 247 return 0;
@@ -728,7 +259,16 @@ int RoadSegAnalysis::check_reverse_driving(cv::Mat direct_mask, sy_rect rc, int @@ -728,7 +259,16 @@ int RoadSegAnalysis::check_reverse_driving(cv::Mat direct_mask, sy_rect rc, int
728 return -1; 259 return -1;
729 } 260 }
730 261
731 -int RoadSegAnalysis::check_cross_line(std::vector<LineInfo>& vec_line, sy_rect rc) { 262 +int RoadSegAnalysis::check_cross_line(std::vector<LineInfo>& vec_line, sy_rect src_rc) {
  263 +
  264 + float scale_w = 640.0 / src_rc.width_;
  265 + float scale_h = 360.0 / src_rc.height_;
  266 +
  267 + sy_rect rc;
  268 + rc.left_ = src_rc.left_ * scale_w;
  269 + rc.width_ = src_rc.width_ * scale_w;
  270 + rc.top_ = src_rc.top_ * scale_h;
  271 + rc.height_ = src_rc.height_ * scale_h;
732 272
733 std::vector<cv::Point> polygon_pts; 273 std::vector<cv::Point> polygon_pts;
734 cv::Point pt_lt; 274 cv::Point pt_lt;
@@ -816,7 +356,123 @@ int RoadSegAnalysis::check_cross_region(std::vector&lt;SegInfo&gt;&amp; vec_reg, sy_rect r @@ -816,7 +356,123 @@ int RoadSegAnalysis::check_cross_region(std::vector&lt;SegInfo&gt;&amp; vec_reg, sy_rect r
816 return -1; 356 return -1;
817 } 357 }
818 358
819 -cv::Mat imshow_lanes(cv::Mat img, const rs_lane* lanes, int lane_count) { 359 +// cv::Mat imshow_lanes(cv::Mat img, const rs_lane* lanes, int lane_count) {
  360 +// float scale_w = img.cols / 640.0;
  361 +// float scale_h = img.rows / 360.0;
  362 +// std::vector<std::pair<std::vector<cv::Point>, int>> combined;
  363 +// lanes_process(lanes, lane_count, combined, scale_w, scale_h);
  364 +
  365 +// for (const auto& lane_info : combined) {
  366 +// const auto& xys = lane_info.first;
  367 +// int cls = lane_info.second;
  368 +// cv::Scalar color(lane_colors[cls][0],lane_colors[cls][1],lane_colors[cls][2]);
  369 +// for (size_t i = 1; i < xys.size(); ++i) {
  370 +// cv::line(img, xys[i - 1], xys[i], color, 4);
  371 +// }
  372 +// }
  373 +
  374 +// return img;
  375 +// }
  376 +
  377 +// void RoadSegAnalysis::post_direct(rs_result one_result, sy_img src){
  378 +// int src_width = src.w_;
  379 +// int src_height = src.h_;
  380 +// int w = 640;
  381 +// int h = 360;
  382 +// float alpha = 0.75;
  383 +// cv::Mat overlayed_direct_img(cv::Size(w,h), CV_8UC3, cv::Scalar(0, 0, 0));
  384 +// // 将车道线标签转换为彩色图像
  385 +// for (int i = 0; i < h; ++i) {
  386 +// for (int j = 0; j < w; ++j) {
  387 +// int idx = one_result.direct_seg[(i * w + j)];
  388 +// overlayed_direct_img.at<cv::Vec3b>(i, j)[0] = seg_colors[idx][0]; // R通道;
  389 +// overlayed_direct_img.at<cv::Vec3b>(i, j)[1] = seg_colors[idx][1]; // G通道
  390 +// overlayed_direct_img.at<cv::Vec3b>(i, j)[2] = seg_colors[idx][2]; // B通道
  391 +// }
  392 +// }
  393 +// cv::resize(overlayed_direct_img, overlayed_direct_img, cv::Size(src_width,src_height), 0, 0, cv::INTER_LINEAR);
  394 +// // 将原始图像和彩色车道线图进行混合
  395 +// // cv::addWeighted(cvImg, alpha, overlayed_direct_img, 1 - alpha, 0, overlayed_direct_img);
  396 +// cv::Mat img_direct_lane = imshow_lanes(overlayed_direct_img, one_result.reg_array, one_result.lane_count);
  397 +// cv::imwrite("img_direct_lane.jpg", img_direct_lane);
  398 +
  399 +
  400 +// std::vector<std::pair<std::vector<cv::Point>, int>> combined;
  401 +// lanes_process(one_result.reg_array, one_result.lane_count, combined);
  402 +// std::vector<std::vector<cv::Point>> poly_masks, lanes, direct_masks, merge_masks;
  403 +// std::vector<int> region_classes, cats, direct_classes, merge_classes;
  404 +// cv::Mat background_mask;
  405 +// std::map<double, int> x_sort;
  406 +// bool large_resolution = false;
  407 +// if (src_height > 1920) large_resolution = true;
  408 +// cv::Mat seg_output = seg_post_process(large_resolution, one_result.seg_array, combined, poly_masks, region_classes, lanes, cats, x_sort, background_mask); //m_masks:mask前的结果 poly_masks后的结果
  409 +// cv::Mat direct_output = direct_post_process(large_resolution, one_result.direct_seg, direct_masks, direct_classes);
  410 +// cv::Mat merge_output = merge_direct_process(large_resolution, one_result.direct_seg, merge_masks, merge_classes);
  411 +
  412 +// cv::Mat image(cv::Size(w,h), CV_8UC3, cv::Scalar(0, 0, 0));
  413 +// cv::Mat vis_image = mask_to_rgb(image, seg_output);
  414 +// cv::Mat direct_image = mask_to_rgb(image, direct_output);
  415 +// cv::Mat merge_image = mask_to_rgb(image, merge_output);
  416 +// cv::imwrite("vis_image.jpg", vis_image);
  417 +// cv::imwrite("direct_image.jpg", direct_image);
  418 +// cv::imwrite("merge_image.jpg", merge_image);
  419 +// cv::imwrite("background_mask.jpg", background_mask);
  420 +// }
  421 +
  422 +
  423 +cv::Mat RoadSegAnalysis::mask_to_rgb(cv::Mat img, cv::Mat mask) {
  424 + cv::Mat masks = img.clone();
  425 + int reg_cls = 8;
  426 + for (int i = 0; i < masks.rows; i++) {
  427 + for (int j = 0; j < masks.cols; j++) {
  428 + for (int k = 1; k < reg_cls; k++) {
  429 + if (mask.at<int>(i,j) == k) {
  430 + masks.at<cv::Vec3b>(i,j)[0] = seg_colors[k][0];
  431 + masks.at<cv::Vec3b>(i,j)[1] = seg_colors[k][1];
  432 + masks.at<cv::Vec3b>(i,j)[2] = seg_colors[k][2];
  433 + }
  434 + }
  435 + }
  436 + }
  437 + return masks;
  438 +}
  439 +
  440 +float RoadSegAnalysis::contourArea(std::vector<cv::Point> contour, cv::Point2f& center) {
  441 + cv::RotatedRect rect = cv::minAreaRect(contour); // 最小外接矩形 rect[0]中心点 rect[1]宽 高 rect[2]旋转角度
  442 + center = rect.center;
  443 + return cv::contourArea(contour);
  444 +}
  445 +
  446 +void RoadSegAnalysis::lanes_process(const rs_lane* lanes, int lane_count, std::vector<std::pair<std::vector<cv::Point>, int>>& combined, float scale_w, float scale_h) {
  447 + std::vector<std::vector<cv::Point> > lanes_xys;
  448 + std::vector<int> lanes_cls;
  449 + for (int i = 0; i < lane_count; i++) {
  450 + std::vector<cv::Point> xys;
  451 + for (int j = 0; j < lanes[i].num_points; j++) {
  452 + int x = static_cast<int>(lanes[i].points[j].x_ * scale_w);
  453 + int y = static_cast<int>(lanes[i].points[j].y_ * scale_h);
  454 + if (x > 0 && y > 0) {
  455 + xys.emplace_back(x, y);
  456 + }
  457 + }
  458 + if (!xys.empty()) {
  459 + lanes_xys.push_back(xys);
  460 + lanes_cls.push_back(lanes[i].cls);
  461 + }
  462 + }
  463 +
  464 + for (size_t i = 0; i < lanes_xys.size(); ++i) {
  465 + combined.push_back(std::make_pair(lanes_xys[i], lanes_cls[i]));
  466 + }
  467 + if (!combined.empty()) {
  468 + //按车道线起点坐标排序,相应的类别顺序也会变化以保证标签对齐
  469 + std::sort(combined.begin(), combined.end(), [](const std::pair<std::vector<cv::Point>, int>& a, const std::pair<std::vector<cv::Point>, int>& b) {
  470 + return a.first[0].x < b.first[0].x;
  471 + });
  472 + }
  473 +}
  474 +
  475 +cv::Mat RoadSegAnalysis::imshow_lanes(cv::Mat img, const rs_lane* lanes, int lane_count) {
820 float scale_w = img.cols / 640.0; 476 float scale_w = img.cols / 640.0;
821 float scale_h = img.rows / 360.0; 477 float scale_h = img.rows / 360.0;
822 std::vector<std::pair<std::vector<cv::Point>, int>> combined; 478 std::vector<std::pair<std::vector<cv::Point>, int>> combined;
@@ -834,47 +490,145 @@ cv::Mat imshow_lanes(cv::Mat img, const rs_lane* lanes, int lane_count) { @@ -834,47 +490,145 @@ cv::Mat imshow_lanes(cv::Mat img, const rs_lane* lanes, int lane_count) {
834 return img; 490 return img;
835 } 491 }
836 492
837 -void RoadSegAnalysis::post_direct(rs_result one_result, sy_img src){  
838 - int src_width = src.w_;  
839 - int src_height = src.h_;  
840 - int w = 640;  
841 - int h = 360;  
842 - float alpha = 0.75;  
843 - cv::Mat overlayed_direct_img(cv::Size(w,h), CV_8UC3, cv::Scalar(0, 0, 0));  
844 - // 将车道线标签转换为彩色图像  
845 - for (int i = 0; i < h; ++i) {  
846 - for (int j = 0; j < w; ++j) {  
847 - int idx = one_result.direct_seg[(i * w + j)];  
848 - overlayed_direct_img.at<cv::Vec3b>(i, j)[0] = seg_colors[idx][0]; // R通道;  
849 - overlayed_direct_img.at<cv::Vec3b>(i, j)[1] = seg_colors[idx][1]; // G通道  
850 - overlayed_direct_img.at<cv::Vec3b>(i, j)[2] = seg_colors[idx][2]; // B通道 493 +int RoadSegAnalysis::Mask2LanePoints(const cv::Mat& pred, std::vector<std::vector<cv::Point>>&lanes, std::vector<int>& cats) {
  494 + std::vector<int> labels = {8, 9, 10, 11};
  495 + for(auto cat: labels) {
  496 + cv::Mat b_masks, measure_labels, stats, centroids;
  497 + cv::compare(pred, cat, b_masks, cv::CMP_EQ); //将pred元素逐个和cat比较,相同255,不同0
  498 + // cv::threshold(pred, b_masks, 126, 255, cv::THRESH_OTSU); //生成二值图
  499 + // 连通域计算 b_masks:闭操作后的二值图像 measure_labels:和原图一样大的标记图 centroids:nccomps×2的矩阵,表示每个连通域的质心(x, y)
  500 + // stats:nccomps×5的矩阵 表示每个连通区域的外接矩形和面积(x, y, w, h, area),索引0是背景信息
  501 + int nccomps = cv::connectedComponentsWithStats (b_masks, measure_labels, stats, centroids, 4); //8
  502 + for(int cv_measure_id = 1; cv_measure_id < nccomps; cv_measure_id++ ) { //跳过背景信息0
  503 + cv::Mat cv_measure_mask;
  504 + cv::compare(measure_labels, cv_measure_id, cv_measure_mask, cv::CMP_EQ);
  505 + std::vector< std::vector< cv::Point> > contours;
  506 + cv::findContours(cv_measure_mask,contours,cv::noArray(),cv::RETR_TREE,cv::CHAIN_APPROX_SIMPLE);
  507 + std::vector<cv::Point> contours_poly;
  508 + for (int j = 0; j < contours.size();j++) {
  509 + float area = cv::contourArea(contours[j]); if (area < 60) continue; //30
  510 + cv::approxPolyDP(cv::Mat(contours[j]), contours_poly, 6, true); //减小epsilon提高拟合精度(需要调试,epsilon过小会使多边形不够简化,单条线变多条)
  511 + if (contours_poly.size() == 1) continue;
  512 + lanes.push_back(contours_poly);
  513 + cats.push_back(cat);
  514 + }
  515 + }
  516 + }
  517 + return 0;
  518 +}
  519 +
  520 +
  521 +cv::Mat RoadSegAnalysis::seg_post_process(bool large_resolution, unsigned char *seg_array, std::vector<std::pair<std::vector<cv::Point>, int>> combined, std::vector<std::vector<cv::Point>> &poly_masks, std::vector<int> &region_classes, std::vector<std::vector<cv::Point>> &lanes, std::vector<int> &cats, std::map<double, int> &x_sort) {
  522 + std::vector<int> pred_cls;
  523 + int h = 360, w = 640;
  524 + cv::Mat lanes_masks = cv::Mat_<int>(h,w); //正常分割结果
  525 + cv::Mat mask_rmlane = cv::Mat_<int>(h,w); //车道线区域置为背景
  526 + cv::Mat solve_masks = cv::Mat_<int>(h,w); //计算主行驶区域用(虚线及减速标线归入行车道)
  527 + int step_size = h*w;
  528 + int seg_min_region_area = 512; //1024
  529 +
  530 + for (int i = 0; i < h; ++i) {
  531 + for (int j = 0; j < w; ++j) {
  532 + int max_cls = seg_array[(i * w + j)];
  533 + lanes_masks.ptr<int>(i)[j] = max_cls;
  534 + pred_cls.push_back(max_cls);
  535 + mask_rmlane.ptr<int>(i)[j] = max_cls;
  536 + solve_masks.ptr<int>(i)[j] = max_cls;
  537 + }
  538 + }
  539 +
  540 + for (const auto& lane_info : combined) {
  541 + const auto& xys = lane_info.first;
  542 + int cls = lane_info.second;
  543 + if (cls == 1) cls = 8; /*黄实线*/ if (cls == 2) cls = 9; /*白实线*/
  544 + if (cls == 3) cls = 10; /*虚线*/ if (cls == 4) cls = 11; /*黄虚线*/
  545 + for (size_t i = 1; i < xys.size(); ++i) {
  546 + cv::line(lanes_masks, xys[i - 1], xys[i], cls, 4); //绘制车道线用于求连通域
  547 + if (cls == 10 || cls == 11) cls = 1; //求主行驶区域时将虚线归入行车道
  548 + cv::line(solve_masks, xys[i - 1], xys[i], cls, 4);
  549 +
851 } 550 }
852 } 551 }
853 - cv::resize(overlayed_direct_img, overlayed_direct_img, cv::Size(src_width,src_height), 0, 0, cv::INTER_LINEAR);  
854 - // 将原始图像和彩色车道线图进行混合  
855 - // cv::addWeighted(cvImg, alpha, overlayed_direct_img, 1 - alpha, 0, overlayed_direct_img);  
856 - cv::Mat img_direct_lane = imshow_lanes(overlayed_direct_img, one_result.reg_array, one_result.lane_count);  
857 - cv::imwrite("img_direct_lane.jpg", img_direct_lane);  
858 552
  553 + /* 求背景区域--mask车道区域,场景变化用
  554 + cv::compare(lanes_masks, 0, background_mask, cv::CMP_EQ); //将lanes_masks元素逐个和0比较,相同255,不同0*/
  555 +#if 1
  556 + //--mask远处区域------------------------------------------------
  557 + cv::Mat mask_black = mask_rmlane.clone();
  558 + if (large_resolution) mask_black(cv::Rect(0, 0, w, int(h * 0.14))) = 0;
  559 + else mask_black(cv::Rect(0, 0, w, int(h * 0.22))) = 0;
  560 + mask_black(cv::Rect(0, int(h * 0.95), w, int(h * 0.05))) = 0;
  561 + mask_black(cv::Rect(0, 0, int(w * 0.02), h)) = 0;
  562 + mask_black(cv::Rect(int(w * 0.95), 0, int(w * 0.05), h)) = 0;
  563 + mask_rmlane = mask_black;
  564 + //-------------------------------------------------------------------------
  565 +#endif
  566 + //2.去重获取预测到的类别
  567 + std::vector<int> labels(pred_cls);
  568 + std::sort(labels.begin(),labels.end());
  569 + labels.erase(std::unique(labels.begin(),labels.end()),labels.end());
  570 +
  571 + //4.求车道线区域
  572 + int flag = Mask2LanePoints(lanes_masks, lanes, cats); ///////////////////////// 车道线如何与mask结合
  573 +
  574 + //5.求道路区域
  575 + int count = 0;
  576 + for(auto cat: labels) {
  577 + // std::cout << cat << std::endl;
  578 + cv::Mat b_masks, measure_labels, stats, centroids;
  579 + cv::Mat n_masks = cv::Mat_<int>(h,w);
  580 + n_masks = cv::Scalar(255);
  581 + cv::compare(mask_rmlane, cat, b_masks, cv::CMP_EQ); //将mask_rmlane元素逐个和cat比较,相同255,不同0
  582 + //连通域计算
  583 + int nccomps = cv::connectedComponentsWithStats (b_masks, measure_labels, stats, centroids, 8);
  584 + for(int i = 1; i < nccomps; i++ ) { //跳过背景信息0
  585 + //移除过小的区域,并将对应位置置为0
  586 + if (stats.at<int>(i, cv::CC_STAT_AREA) < seg_min_region_area) {
  587 + cv::Mat comparison_result;
  588 + cv::compare(measure_labels, cv::Scalar(i), comparison_result, cv::CMP_EQ); //相等为255不等为0
  589 + n_masks.setTo(0, comparison_result); // 将comparison_result中非零区域置为0
  590 +
  591 + cv::bitwise_and(mask_rmlane,n_masks,mask_rmlane);
  592 + continue;
  593 + }
859 594
860 - std::vector<std::pair<std::vector<cv::Point>, int>> combined;  
861 - lanes_process(one_result.reg_array, one_result.lane_count, combined);  
862 - std::vector<std::vector<cv::Point>> poly_masks, lanes, direct_masks, merge_masks;  
863 - std::vector<int> region_classes, cats, direct_classes, merge_classes;  
864 - cv::Mat background_mask;  
865 - std::map<double, int> x_sort;  
866 - bool large_resolution = false;  
867 - if (src_height > 1920) large_resolution = true;  
868 - cv::Mat seg_output = seg_post_process(large_resolution, one_result.seg_array, combined, poly_masks, region_classes, lanes, cats, x_sort, background_mask); //m_masks:mask前的结果 poly_masks后的结果  
869 - cv::Mat direct_output = direct_post_process(large_resolution, one_result.direct_seg, direct_masks, direct_classes);  
870 - cv::Mat merge_output = merge_direct_process(large_resolution, one_result.direct_seg, merge_masks, merge_classes);  
871 -  
872 - cv::Mat image(cv::Size(w,h), CV_8UC3, cv::Scalar(0, 0, 0));  
873 - cv::Mat vis_image = mask_to_rgb(image, seg_output);  
874 - cv::Mat direct_image = mask_to_rgb(image, direct_output);  
875 - cv::Mat merge_image = mask_to_rgb(image, merge_output);  
876 - cv::imwrite("vis_image.jpg", vis_image);  
877 - cv::imwrite("direct_image.jpg", direct_image);  
878 - cv::imwrite("merge_image.jpg", merge_image);  
879 - cv::imwrite("background_mask.jpg", background_mask); 595 + double centr_x = centroids.at<double>(i, 0);
  596 + double centr_y = centroids.at<double>(i, 1);
  597 +
  598 + int region_class = cat;
  599 + // printf("region_class: %d\n", region_class);
  600 + cv::Mat region_mask;
  601 + cv::bitwise_and(measure_labels,n_masks,measure_labels);/////
  602 + cv::compare(measure_labels, i, region_mask, cv::CMP_EQ);
  603 +
  604 + std::vector< std::vector< cv::Point> > contours;
  605 + cv::findContours(region_mask,contours,cv::noArray(),cv::RETR_TREE,cv::CHAIN_APPROX_SIMPLE);
  606 + std::vector<cv::Point> contours_poly;
  607 + for (int j = 0; j < contours.size();j++) {
  608 + cv::approxPolyDP(cv::Mat(contours[j]), contours_poly, 10, true);
  609 + if (contours_poly.size() <= 2) continue;
  610 + poly_masks.push_back(contours_poly);
  611 + region_classes.push_back(cat);
  612 + if (x_sort.count(centr_x)) centr_x += 0.0001;
  613 + x_sort.insert(std::make_pair(centr_x, count));
  614 + ++ count;
  615 + // for (auto iter: contours_poly) {
  616 + // std::cout << "contour " << iter << " " << cat << std::endl;
  617 + // }
  618 +
  619 + }
  620 + }
  621 + }
  622 +
  623 +#if 0
  624 + //6.draw lanes
  625 + for (int i = 0; i < lanes.size(); ++i) {
  626 + int thickness = 4;
  627 + for (int j = 0; j < lanes[i].size()-1; ++j) {
  628 + cv::line(mask_rmlane, lanes[i][j], lanes[i][j+1], {seg_colors[cats[i]][0],seg_colors[cats[i]][1],seg_colors[cats[i]][2]}, thickness);
  629 + // std::cout << lanes[i][j] << " " << lanes[i][j+1] << " " << cats[i] << std::endl;
  630 + }
  631 + }
  632 +#endif
  633 + return mask_rmlane;
880 } 634 }
881 \ No newline at end of file 635 \ No newline at end of file
src/ai_engine_module/RoadSegAnalysis.h
@@ -9,8 +9,7 @@ using namespace std; @@ -9,8 +9,7 @@ using namespace std;
9 struct RoadInfo{ 9 struct RoadInfo{
10 std::vector<LineInfo> vec_line; 10 std::vector<LineInfo> vec_line;
11 std::vector<SegInfo> vec_road; 11 std::vector<SegInfo> vec_road;
12 -  
13 - cv::Mat direct_mask; 12 + std::vector<SegInfo> vec_direct;
14 }; 13 };
15 14
16 class RoadSegAnalysis 15 class RoadSegAnalysis
@@ -23,7 +22,7 @@ public: @@ -23,7 +22,7 @@ public:
23 22
24 std::vector<RoadInfo> detect(vector<sy_img> vec_img); 23 std::vector<RoadInfo> detect(vector<sy_img> vec_img);
25 24
26 - int check_reverse_driving(cv::Mat direct_mask, sy_rect rc, int src_width, int src_height, int head_or_tail); 25 + int check_reverse_driving(std::vector<SegInfo>& vec_direct, sy_rect rc, int src_width, int src_height, int head_or_tail);
27 26
28 int check_cross_line(std::vector<LineInfo>& vec_line, sy_rect rc); 27 int check_cross_line(std::vector<LineInfo>& vec_line, sy_rect rc);
29 28
@@ -32,11 +31,20 @@ public: @@ -32,11 +31,20 @@ public:
32 private: 31 private:
33 int release(); 32 int release();
34 33
35 - std::vector<SegInfo> parse_seg(rs_result one_result, sy_img src); 34 + RoadInfo parse_road(rs_result one_result, sy_img src);
  35 +
  36 + std::vector<SegInfo> parse_direct(rs_result one_result, sy_img src);
  37 +
  38 + // void post_direct(rs_result one_result, sy_img src);
  39 +
36 40
37 - cv::Mat parse_direct(rs_result one_result, sy_img src); 41 + cv::Mat mask_to_rgb(cv::Mat img, cv::Mat mask);
  42 + float contourArea(std::vector<cv::Point> contour, cv::Point2f& center);
  43 + void lanes_process(const rs_lane* lanes, int lane_count, std::vector<std::pair<std::vector<cv::Point>, int>>& combined, float scale_w = 1.0, float scale_h = 1.0);
  44 + cv::Mat imshow_lanes(cv::Mat img, const rs_lane* lanes, int lane_count);
  45 + int Mask2LanePoints(const cv::Mat& pred, std::vector<std::vector<cv::Point>>&lanes, std::vector<int>& cats);
  46 + cv::Mat seg_post_process(bool large_resolution, unsigned char *seg_array, std::vector<std::pair<std::vector<cv::Point>, int>> combined, std::vector<std::vector<cv::Point>> &poly_masks, std::vector<int> &region_classes, std::vector<std::vector<cv::Point>> &lanes, std::vector<int> &cats, std::map<double, int> &x_sort);
38 47
39 - void post_direct(rs_result one_result, sy_img src);  
40 private: 48 private:
41 void* m_handle{nullptr}; 49 void* m_handle{nullptr};
42 aclrtContext ctx{nullptr}; 50 aclrtContext ctx{nullptr};
src/village_inc.h
@@ -36,10 +36,11 @@ typedef struct VehicleInfo { @@ -36,10 +36,11 @@ typedef struct VehicleInfo {
36 manned_result manned_res; 36 manned_result manned_res;
37 37
38 int type; 38 int type;
39 - 39 +
40 int vpt_type; 40 int vpt_type;
41 int rainshed; //是否安装雨棚, 0 有雨棚 1 无雨棚 41 int rainshed; //是否安装雨棚, 0 有雨棚 1 无雨棚
42 - int manned; 42 + int truck_manned;
  43 + int motor_manned;
43 44
44 int human_upper_color; 45 int human_upper_color;
45 int human_lower_color; 46 int human_lower_color;