在HDevelop中
dev_close_window () read_image (Image, 'D:/bb/tu/7.jpg') rgb1_to_gray (Image, GrayImage) edges_sub_pix (GrayImage, Edges, 'canny', 1, 5, 10) segment_contours_xld (Edges, ContoursSplit, 'lines_circles', 5, 4, 2) *分割xld輪廓 *參數1:需要進行分割的輪廓 *參數2:分割后的輪廓tuple *參數3:分割輪廓的方式 * 'lines' 將輸入輪廓分割成線條 * 'lines_circles' 將其分割成線條和圓弧 * 'lines_ellipses' 將其分割成線條和橢圓弧 *參數4:輪廓平滑的參數,可以抑制在折線逼近過程中過短的線段 * 注意:不能等於0;最好大於等於3並且是奇數;建議值是5 *參數5:第一次用Ramer算法(即用直線段遞進逼近輪廓)時的MaxLineDist,在逼近完 * 成之后,再用圓弧或橢圓弧對相鄰分割線段進行擬合,如果擬合圓弧到輪廓的距 * 離小於逼近線段到輪廓的距離,就用圓弧替代逼近線段,這個過程一致迭代直到 * 所有的線段擬合完畢。 *參數6:第二次逼近輪廓時的MaxLineDist * 只有當MaxLineDist2這種兩步逼近算法效率較高,因為在第一次逼近過程中,遞進 * 逼近的直線段較少,因此較大直徑的圓弧能夠被高效的分割出來。在第二次逼近過程 * 中,能夠被小直徑圓弧逼近的輪廓被找到,同時大直徑圓弧的末端被重新定義 count_obj (ContoursSplit, Number) *9 gen_empty_obj (Lines) *實例化一個空對象 gen_empty_obj(Circles) for I:=1 to Number by 1 *遍歷 select_obj (ContoursSplit, ObjectSelected, I) get_contour_global_attrib_xld (ObjectSelected, 'cont_approx', Attrib) *返回XLD輪廓的全局屬性名的值,全局屬性是為每個輪廓定義的附加值 *參數1:xld輪廓 *參數2:全局屬性名,包含如下: * 'regr_norm_row' * 'regr_norm_col' * 'regr_mean_dist' * 'regr_dev_dist' * 'cont_approx' * 可判斷輪廓段的種類是直線、圓弧 還是 橢圓弧 具體如下: * cont_approx = -1 對應XLD為直線,可以擬合為直線 * cont_approx = 0 對應XLD為圓,可以擬合為圓 * cont_approx = 1 對應XLD為橢圓,可以擬合為橢圓 * 'bright_dark' * 'is_hole' *參數3:返回的屬性值 if(Attrib=-1) concat_obj (Lines, ObjectSelected, Lines) *兩個區域組合成區域集 else concat_obj (Circles, ObjectSelected, Circles) endif endfor get_image_size (GrayImage, Width, Height) dev_open_window(10,10,Width, Height,'black',WindowHandle) dev_display(Lines) dev_open_window(10,10,Width, Height,'black',WindowHandle1) dev_display(Circles)
在QtCreator中
HObject ho_Image, ho_GrayImage, ho_Edges, ho_ContoursSplit;
HObject ho_Lines, ho_Circles, ho_ObjectSelected;
HTuple hv_Number, hv_I, hv_Attrib, hv_Width;
HTuple hv_Height, hv_WindowHandle, hv_WindowHandle1;
ReadImage(&ho_Image, "D:/bb/tu/7.jpg"); Rgb1ToGray(ho_Image, &ho_GrayImage); EdgesSubPix(ho_GrayImage, &ho_Edges, "canny", 1, 5, 10); SegmentContoursXld(ho_Edges, &ho_ContoursSplit, "lines_circles", 5, 4, 2); //分割xld輪廓 //參數1:需要進行分割的輪廓 //參數2:分割后的輪廓tuple //參數3:分割輪廓的方式 // 'lines' 將輸入輪廓分割成線條 // 'lines_circles' 將其分割成線條和圓弧 // 'lines_ellipses' 將其分割成線條和橢圓弧 //參數4:輪廓平滑的參數,可以抑制在折線逼近過程中過短的線段 // 注意:不能等於0;最好大於等於3並且是奇數;建議值是5 //參數5:第一次用Ramer算法(即用直線段遞進逼近輪廓)時的MaxLineDist,在逼近完 // 成之后,再用圓弧或橢圓弧對相鄰分割線段進行擬合,如果擬合圓弧到輪廓的距 // 離小於逼近線段到輪廓的距離,就用圓弧替代逼近線段,這個過程一致迭代直到 // 所有的線段擬合完畢。 //參數6:第二次逼近輪廓時的MaxLineDist // 只有當MaxLineDist2這種兩步逼近算法效率較高,因為在第一次逼近過程中,遞進 // 逼近的直線段較少,因此較大直徑的圓弧能夠被高效的分割出來。在第二次逼近過程 // 中,能夠被小直徑圓弧逼近的輪廓被找到,同時大直徑圓弧的末端被重新定義 CountObj(ho_ContoursSplit, &hv_Number); //9 GenEmptyObj(&ho_Lines); //實例化一個空對象 GenEmptyObj(&ho_Circles); { HTuple end_val31 = hv_Number; HTuple step_val31 = 1; for (hv_I=1; hv_I.Continue(end_val31, step_val31); hv_I += step_val31) { //遍歷 SelectObj(ho_ContoursSplit, &ho_ObjectSelected, hv_I); GetContourGlobalAttribXld(ho_ObjectSelected, "cont_approx", &hv_Attrib); //返回XLD輪廓的全局屬性名的值,全局屬性是為每個輪廓定義的附加值 //參數1:xld輪廓 //參數2:全局屬性名,包含如下: // 'regr_norm_row' // 'regr_norm_col' // 'regr_mean_dist' // 'regr_dev_dist' // 'cont_approx' // 可判斷輪廓段的種類是直線、圓弧 還是 橢圓弧 具體如下: // cont_approx = -1 對應XLD為直線,可以擬合為直線 // cont_approx = 0 對應XLD為圓,可以擬合為圓 // cont_approx = 1 對應XLD為橢圓,可以擬合為橢圓 // 'bright_dark' // 'is_hole' //參數3:返回的屬性值 if (0 != (hv_Attrib==-1)) { ConcatObj(ho_Lines, ho_ObjectSelected, &ho_Lines); //兩個區域組合成區域集 } else { ConcatObj(ho_Circles, ho_ObjectSelected, &ho_Circles); } } } GetImageSize(ho_GrayImage, &hv_Width, &hv_Height); SetWindowAttr("background_color","black"); OpenWindow(10,10,hv_Width,hv_Height,0,"visible","",&hv_WindowHandle); HDevWindowStack::Push(hv_WindowHandle); if (HDevWindowStack::IsOpen()) DispObj(ho_Lines, HDevWindowStack::GetActive()); SetWindowAttr("background_color","black"); OpenWindow(10,10,hv_Width,hv_Height,0,"visible","",&hv_WindowHandle1); HDevWindowStack::Push(hv_WindowHandle1); if (HDevWindowStack::IsOpen()) DispObj(ho_Circles, HDevWindowStack::GetActive());