智能车八邻域算法

做智能车比赛的时候学到的八邻域搜线,代码仅供参考学习,不能直接使用

         //八邻域搜线
         if(left_findflag)
         {
             L_edge[0].row = jilu_row_l;
             L_edge[0].col = jilu_col_l;
             L_edge[0].flag = 1;
             uint8 curr_row = jilu_row_l;
             uint8 curr_col = jilu_col_l;
             dire_left = 0; 
             center_turn_flag = 1;
           
             for(int i = 1;i < L_search_amount; i++)   
             {
               
                 if(curr_row < L_edge_end_row || curr_row>Image_H-1||curr_row+1<L_edge_end_row)  break;
                 if(curr_col > max_col || curr_col < min_col)
                 {
                     if(++L_search_edge_count == 3)
                         break;
                 }
                 else
                     L_search_edge_count = 0;
             
                 if(dire_left != 2&&black_(image[curr_row-1][curr_col-1])&&white_(image[curr_row-1][curr_col]))   
                 {
                     curr_row = curr_row -1;
                     curr_col = curr_col -1;
                     L_edge_count = L_edge_count +1;
                     dire_left = 7;
                     L_edge[i].row = curr_row;
                     L_edge[i].col = curr_col;
                     L_edge[i].flag = 1;
                 }
                 else if(dire_left!=3&&black_(image[curr_row-1][curr_col+1])&&white_(image[curr_row][curr_col+1]))   
                 {
                     curr_row = curr_row -1;
                     curr_col = curr_col + 1;
                     L_edge_count = L_edge_count + 1;
                     dire_left = 6;
                     L_edge[i].row = curr_row;
                     L_edge[i].col = curr_col;
                     L_edge[i].flag = 1;
                 }
                 else if(black_(image[curr_row-1][curr_col])&&white_(image[curr_row-1][curr_col+1]))                  
                 {
                     curr_row = curr_row - 1;
                     L_edge_count = L_edge_count + 1;
                     dire_left = 0;
                     L_edge[i].row = curr_row;
                     L_edge[i].col = curr_col;
                     L_edge[i].flag = 1;
                 }
                 else if(dire_left!=5&&black_(image[curr_row][curr_col-1])&&white_(image[curr_row-1][curr_col-1])) 
                 {
                     curr_col = curr_col - 1;
                     L_edge_count = L_edge_count +1;
                     dire_left = 4;
                     L_edge[i].row = curr_row;
                     L_edge[i].col = curr_col;
                     L_edge[i].flag = 1;
                 }
                 else if(dire_left!=4&&black_(image[curr_row][curr_col+1])&&white_(image[curr_row+1][curr_col+1]))  
                 {
                     curr_col = curr_col + 1;
                     L_edge_count = L_edge_count +1;
                     dire_left = 5;
                     L_edge[i].row = curr_row;
                     L_edge[i].col = curr_col;
                     L_edge[i].flag = 1;
                 }
                 else if(dire_left!=6&&black_(image[curr_row+1][curr_col-1])&&white_(image[curr_row][curr_col-1]))   
                 {
                     curr_row = curr_row + 1;
                     curr_col = curr_col -1;
                     L_edge_count = L_edge_count +1;
                     dire_left = 3;
                     L_edge[i].row = curr_row;
                     L_edge[i].col = curr_col;
                     L_edge[i].flag = 1;
                 }
                 else if(dire_left!=7&&black_(image[curr_row+1][curr_col+1])&&white_(image[curr_row+1][curr_col]))    
                 {
                     curr_row = curr_row + 1;
                     curr_col = curr_col + 1;
                     L_edge_count = L_edge_count +1;
                     dire_left = 2;
                     L_edge[i].row = curr_row;
                     L_edge[i].col = curr_col;
                     L_edge[i].flag = 1;
                 }
                 else
                     break;
             }
         }
         if(right_findflag)
         {
             R_edge[0].row = jilu_row_r;
             R_edge[0].col = jilu_col_r;
             R_edge[0].flag = 1;
             uint8 curr_row = jilu_row_r;
             uint8 curr_col = jilu_col_r;
             dire_right = 0;
             for(int i = 1;i<R_search_amount;i++)
             {
                 if(curr_row < L_edge_end_row ||curr_row>Image_H-1||curr_row+1<L_edge_end_row)  break;
                 if(curr_col > max_col || curr_col < min_col)
                 {
                     if(++R_search_edge_count == 3)
                         break;
                 }
                 else   R_search_edge_count = 0;

                 if(curr_col<Image_W&&dire_right!=3&&black_(image[curr_row-1][curr_col+1])&&white_(image[curr_row-1][curr_col])) 
                 {
                     curr_row = curr_row - 1;
                     curr_col = curr_col + 1;
                     R_edge_count = R_edge_count + 1;
                     dire_right = 6;
                     R_edge[i].row = curr_row;
                     R_edge[i].col = curr_col;
                     R_edge[i].flag = 1;
                 }
                 else if(dire_right!=2&&black_(image[curr_row-1][curr_col-1])&&white_(image[curr_row][curr_col-1])) 
                 {
                     curr_row = curr_row-1;
                     curr_col = curr_col-1;
                     R_edge_count = R_edge_count + 1;
                     dire_right = 7;
                     R_edge[i].row = curr_row;
                     R_edge[i].col = curr_col;
                     R_edge[i].flag = 1;
                 }
                 else if(black_(image[curr_row-1][curr_col])&&white_(image[curr_row-1][curr_col-1]))                  
                 {
                     curr_row = curr_row - 1;
                     R_edge_count = R_edge_count + 1;
                     dire_right = 0;
                     R_edge[i].row = curr_row;
                     R_edge[i].col = curr_col;
                     R_edge[i].flag = 1;
                 }
                 else if(dire_right!=5&&black_(image[curr_row][curr_col-1])&&white_(image[curr_row+1][curr_col-1]))
                 {
                     curr_col = curr_col-1;
                     R_edge_count = R_edge_count + 1;
                     dire_right = 4;
                     R_edge[i].row = curr_row;
                     R_edge[i].col = curr_col;
                     R_edge[i].flag = 1;
                 }

                 else if(dire_right!=4&&black_(image[curr_row][curr_col+1])&&white_(image[curr_row-1][curr_col+1]))
                 {
                     curr_col = curr_col + 1;
                     R_edge_count = R_edge_count + 1;
                     dire_right = 5;
                     R_edge[i].row = curr_row;
                     R_edge[i].col = curr_col;
                     R_edge[i].flag = 1;
                 }
                 else if(dire_right!=6&&black_(image[curr_row+1][curr_col-1])&&white_(image[curr_row+1][curr_col]))   
                 {
                     curr_row = curr_row + 1;
                     curr_col = curr_col - 1;
                     R_edge_count = R_edge_count + 1;
                     dire_right = 3;
                     R_edge[i].row = curr_row;
                     R_edge[i].col = curr_col;
                     R_edge[i].flag = 1;
                 }
                 else if(dire_right!=7&&black_(image[curr_row+1][curr_col+1])&&white_(image[curr_row][curr_col+1]))  
                 {
                     curr_row = curr_row + 1;
                     curr_col = curr_col + 1;
                     R_edge_count = R_edge_count + 1;
                     dire_right = 2;
                     R_edge[i].row = curr_row;
                     R_edge[i].col = curr_col;
                     R_edge[i].flag = 1;
                 }
                 else
                     break;
             }
         }
         if(left_findflag)
         {
             for(int i= 1;i<L_edge_count -1;i++)
             {
                 L_edge[i].row = (L_edge[i].row + L_edge[i+1].row)/2;
                 L_edge[i].col = (L_edge[i].col + L_edge[i+1].col)/2;
             }
             for(int i= L_edge_count-1;i>1;i--)
             {
                 L_edge[i].row = (L_edge[i].row + L_edge[i-1].row)/2;
                 L_edge[i].col = (L_edge[i].col + L_edge[i-1].col)/2;
             }
             edge_process_flag = 0; 
             if(L_edge_count >=70)
             {
                 num_cnt = 0;
                 L_count = L_edge_count/2;
                 while(L_count<L_edge_count)
                 {
                     if(L_edge[L_count].row == L_edge[L_count+1].row)
                         num_cnt = num_cnt +1;
                     else
                         num_cnt = 0;
                     if(num_cnt > 5)
                         break;
                     L_count = L_count +1;
                 }
                 L_edge_count = L_count;
             }
         }
         if(right_findflag)
         {
             for(int i = 1;i<R_edge_count-1;i++)
             {
                 R_edge[i].row = (R_edge[i].row + R_edge[i+1].row)/2;
                 R_edge[i].col = (R_edge[i].col + R_edge[i-1].col)/2;
             }
             for(int i = R_edge_count-1;i>1;i--)
             {
                 R_edge[i].row = (R_edge[i].row + R_edge[i+1].row)/2;
                 R_edge[i].col = (R_edge[i].col + R_edge[i-1].col)/2;
             }
             if(R_edge_count>=70)  
             {
                 num_cnt = 0;
                 R_count = R_edge_count/2;
                 while(R_count < R_edge_count)
                 {
                     if(R_edge[R_count].row == R_edge[R_count+1].row)
                         num_cnt = num_cnt + 1;
                     else
                         num_cnt = 0;
                     if(num_cnt > 5)
                         break;
                     R_count = R_count + 1;
                 }
                 R_edge_count = R_count;
             }
         }
         if(fabs(L_edge[0].col-L_edge[L_edge_count].col)>Image_W/2&&fabs(L_edge[0].col-L_edge[L_edge_count].col)>Image_W/2)
             enable_check_l_r_edge_same = 1;
         if(enable_check_l_r_edge_same)
         {
             uint8 i_left = L_edge_count - 1;
             uint8 chongdie_cnt = 0;
             for(int i = 0;i<R_edge_count;i++)
             {
                 if(fabs(R_edge[i].row-L_edge[i_left].row)<5&&fabs(R_edge[i].col-L_edge[i_left].col)<5)
                 {
                     chongdie_cnt = chongdie_cnt + 1;
                     i_left = i_left - 1;
                     if(chongdie_cnt > 3) break;
                     if(i_left<0)   break;
                 }
             }
             if(chongdie_cnt>=2)
             {
                 x2 = fabs(L_edge[0].row-R_edge[0].row);
                 if(fabs(L_edge[0].row-R_edge[0].row)>=15)
                 {
                     if(L_edge[0].row>R_edge[0].row)  
                         left_findflag = 0;
                     else if(R_edge[0].row>L_edge[0].row)   
                         right_findflag = 0;
                 }
                 else if(fabs(L_edge[0].row-R_edge[0].row)<15)
                 {

                 }
             }
         }
         if(L_edge_count <10)
             left_findflag = 0;
         if(R_edge_count <10)
             right_findflag = 0;
         if(left_findflag && right_findflag)
         {
             if(jilu_col_l>jilu_col_r)
             {
                 if(jilu_row_l>jilu_row_r)
                     left_findflag = 0;
                 else if(jilu_row_l<jilu_row_r)
                     right_findflag = 0;
             }
         }
         if(L_edge_count-R_edge_count>30&&right_findflag) 
         {
             right_findflag = 0;
             R_edge_count = 0;
         }
         if(R_edge_count-L_edge_count>30&&left_findflag)   
         {
             left_findflag = 0;
             L_edge_count = 0;
         }
         if(left_findflag&&right_findflag)
         {
             if(jilu_row_r-jilu_row_l>Image_H/2&&L_edge_count-R_edge_count>10)
             {
                 right_findflag = 0;
                 R_edge_count = 0;
             }
             else if(jilu_row_l-jilu_row_r>Image_H/2&&R_edge_count-L_edge_count>10)
             {
                 left_findflag = 0;
                 L_edge_count = 0;
             }
         }
         if(L_edge[L_edge_count-1].row - L_edge[1].row>-10) 
             left_findflag = 0;
         if(R_edge[R_edge_count-1].row - R_edge[1].row>-10)  
             right_findflag = 0;
         if(left_findflag || right_findflag)
             enable_midline = 1;
         else
             enable_midline = 0;
         if(enable_L_corner) 
         {
             if(L_edge_count > 9)
             {
                 for(int i = 0; i<L_edge_count-9;i++)
                 {
                     if(L_edge[i+4].row>5)
                     {
                         if((L_edge[i].col - L_edge[i + 4].col) * (L_edge[i + 8].col - L_edge[i + 4].col) +
                            (L_edge[i].row - L_edge[i + 4].row) * (L_edge[i + 8].row - L_edge[i + 4].row) > 0)
                         {
                             L_corner_angle = Get_angle(L_edge[i].row, L_edge[i].col, L_edge[i + 4].row, L_edge[i + 4].col, L_edge[i + 8].row, L_edge[i + 8].col);
                             if(L_edge[i+4].col>L_edge[i+8].col)  
                             {
                                 L_corner_flag = 1;
                                 L_corner_row = L_edge[i+4].row;
                                 L_corner_col = L_edge[i+4].col;
                                 break;
                             }
                         }
                     }
                 }
             }
         }
         if(enable_R_corner) 
         {
             if(R_edge_count > 9)
             {
                 for(int i = 0; i<R_edge_count-9;i++)
                 {
                     if(R_edge[i+4].row>5)
                     {
                         if((R_edge[i].col - R_edge[i + 4].col) * (R_edge[i + 8].col - R_edge[i + 4].col) +
                         (R_edge[i].row - R_edge[i + 4].row) * (R_edge[i + 8].row - R_edge[i + 4].row) > 0) 
                         {
                             R_corner_angle = Get_angle(R_edge[i].row, R_edge[i].col, R_edge[i + 4].row, R_edge[i + 4].col, R_edge[i + 8].row, R_edge[i + 8].col);
                             if(R_edge[i+8].col>R_edge[i+4].col) 
                             {
                                 R_corner_flag = 1;
                                 R_corner_row = R_edge[i+4].row;
                                 R_corner_col = R_edge[i+4].col;
                                 break;
                             }
                         }
                     }
                 }
             }
         }
     }
``
如果您想使用邻域来进行巡线,您可以使用OpenCV和Python来实现。下面是一个示例代码,展示了如何使用邻域进行巡线: ```python import cv2 import numpy as np # 读取图像 image = cv2.imread("line_image.jpg") # 转换为灰度图像 gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 二值化图像 ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) # 提取边缘 edges = cv2.Canny(binary,50, 150) # 获取图像尺寸 height, width = edges.shape # 定义个方向的像素位移 dx = [-1, -1, 0, 1, 1, 1, 0, -1] dy = [0, 1, 1, 1, 0, -1, -1, -1] # 初始化起始位置 start_x = int(width / 2) start_y = height - 1 # 巡线过程 current_x = start_x current_y = start_y path = [(current_x, current_y)] while current_y > 0: max_intensity = 0 next_x = current_x next_y = current_y for i in range(8): new_x = current_x + dx[i] new_y = current_y + dy[i] if new_x >= 0 and new_x < width and new_y >= 0 and new_y < height: intensity = edges[new_y, new_x] if intensity > max_intensity: max_intensity = intensity next_x = new_x next_y = new_y current_x = next_x current_y = next_y path.append((current_x, current_y)) # 绘制巡线路径 for point in path: cv2.circle(image, point, 1, (0, 0, 255), -1) # 显示结果 cv2.imshow("Line Following", image) cv2.waitKey(0) cv2.destroyAllWindows() ``` 在上述代码中,我们首先读取图像并将其转换为灰度图像。然后,对图像进行二值化处理,并使用Canny边缘检测算法提取边缘。接下来,我们定义了个方向的像素位移,并初始化起始位置为图像底部中间位置。然后,我们通过选择具有最大边缘强度的相邻像素来进行巡线,并将路径上的像素保存在`path`列表中。最后,我们将巡线路径绘制在原始图像上,并显示结果。 请注意,上述代码仅是一个简单的示例,您可能需要根据您的实际应用进行适当的调整和优化。 希望这可以帮助到您!如果您有任何进一步的问题,请随时提问。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值