侧面矫正,仿射变换

  • This example program shows how to rectify a part of an image using
  • vector_to_proj_hom_mat2d. This is done by extracting the four
  • corners of a soccer field from an oblique view of a stadium. The four
  • corners define a quadrilateral, which is then mapped to a rectangle
  • that has the correct aspect ratio. If the dimensions of the field were
  • known metrically, the program could be extended to perform metric
  • measurements on the soccer field and stadium track.
    dev_update_off ()
    read_image (Image, ‘olympic_stadium’)
    get_image_size (Image, Width, Height)
    dev_close_window ()
    dev_open_window (0, 0, Width, Height, ‘black’, WindowHandle)
    set_display_font (WindowHandle, 16, ‘mono’, ‘true’, ‘false’)
    dev_display (Image)
    disp_message (WindowHandle, ‘Oblique view of stadium track and field’, ‘image’, -1, -1, ‘black’, ‘true’)
    disp_continue_message (WindowHandle, ‘black’, ‘true’)
    stop ()
  • Segment the field based on its green color and its shape. This is done
  • most easily by using the Hue channel of the HSV transform of the image.
    decompose3 (Image, ImageR, ImageG, ImageB)
    trans_from_rgb (ImageR, ImageG, ImageB, ImageH, ImageS, ImageV, ‘hsv’)
    threshold (ImageH, GreenRegion, 60, 90)
    connection (GreenRegion, ConnectedRegions)
  • Select the field region based on the fact that it is the largest component
  • that roughly looks like a rotated rectangle.
    select_shape_std (ConnectedRegions, RectangleRegions, ‘rectangle2’, 80)
    select_shape_std (RectangleRegions, Field, ‘max_area’, 90)
  • Construct a ROI for the color edge extraction from the boundary of the
  • segmented field.
    shape_trans (Field, FieldConvex, ‘convex’)
    boundary (FieldConvex, FieldBorder, ‘inner’)
    dilation_rectangle1 (FieldBorder, FieldDilation, 7, 7)
    dev_display (Image)
    dev_set_draw (‘margin’)
    dev_display (FieldDilation)
    dev_set_draw (‘fill’)
    disp_message (WindowHandle, ‘Field ROI based on color segmentation’, ‘image’, -1, -1, ‘black’, ‘true’)
    disp_continue_message (WindowHandle, ‘black’, ‘true’)
    stop ()
  • Perform the color edge extraction.
    reduce_domain (Image, FieldDilation, ImageReduced)
    edges_color_sub_pix (ImageReduced, Edges, ‘canny’, 1.5, 20, 40)
    dev_display (Image)
    dev_display (Edges)
    disp_message (WindowHandle, ‘Extracted color edges’, ‘image’, -1, -1, ‘black’, ‘true’)
    disp_continue_message (WindowHandle, ‘black’, ‘true’)
    stop ()
  • Now select straight edges from the extracted edges and group them into
  • the four sides of the quadrilateral.
    select_shape_xld (Edges, SelectedEdges, ‘contlength’, ‘and’, 15, 500)
  • We first need to segment the edges into straight lines because the
  • extracted edges may represent more than one side of the quadrilateral.
    segment_contours_xld (SelectedEdges, ContoursSplit, ‘lines’, 5, 4, 2)
    regress_contours_xld (ContoursSplit, RegressContours, ‘no’, 1)
  • Weed out edges that are not straight enough.
    select_contours_xld (RegressContours, SelectedContours, ‘curvature’, 0, 0.5, 0, 0)
  • Select edges that are long enough to provide meaningful direction information.
    select_shape_xld (SelectedContours, SelectedEdges, ‘contlength’, ‘and’, 15, 500)
  • Group the straight lines into the quadrilateral’s sides.
    union_collinear_contours_xld (SelectedEdges, UnionContours, 30, 1, 4, 0.1, ‘attr_forget’)
    dev_display (Image)
    dev_display (UnionContours)
    disp_message (WindowHandle, ‘Selected straight edges’, ‘image’, -1, -1, ‘black’, ‘true’)
    disp_continue_message (WindowHandle, ‘black’, ‘true’)
    stop ()
  • Now we need to determine the order of the sides because we want to
  • intersect the sides to get the corners of the quadrilateral. First, we
  • separate the sides into roughly horizontal and roughly vertical sides.
    select_shape_xld (UnionContours, HorizontalEdges, ‘phi’, ‘and’, rad(-20), rad(20))
    select_shape_xld (UnionContours, VerticalEdges, [‘phi’,‘phi’], ‘or’, [rad(-90),rad(60)], [rad(-60),rad(90)])
  • Now we need to order the sides. The horizontal sides are sorted based on
  • their row coordinates, while the vertical sides are sorted based on their
  • column coordinates.
    fit_line_contour_xld (HorizontalEdges, ‘tukey’, -1, 0, 10, 2, RowBegHor, ColBegHor, RowEndHor, ColEndHor, NrHor, NcHor, DistHor)
    IndexHor := sort_index(RowBegHor)
    fit_line_contour_xld (VerticalEdges, ‘tukey’, -1, 0, 10, 2, RowBegVer, ColBegVer, RowEndVer, ColEndVer, NrVer, NcVer, DistVer)
    IndexVer := sort_index(ColBegVer)
  • After we have sorted the sides, we can intersect the appropriate sides
  • to get the four corners of the quadrilateral.
    intersection_lines (RowBegHor[IndexHor[0]], ColBegHor[IndexHor[0]], RowEndHor[IndexHor[0]], ColEndHor[IndexHor[0]], RowBegVer[IndexVer[0]], ColBegVer[IndexVer[0]], RowEndVer[IndexVer[0]], ColEndVer[IndexVer[0]], RowUL, ColUL, IsOverlapping)
    intersection_lines (RowBegHor[IndexHor[0]], ColBegHor[IndexHor[0]], RowEndHor[IndexHor[0]], ColEndHor[IndexHor[0]], RowBegVer[IndexVer[1]], ColBegVer[IndexVer[1]], RowEndVer[IndexVer[1]], ColEndVer[IndexVer[1]], RowUR, ColUR, IsOverlapping)
    intersection_lines (RowBegHor[IndexHor[1]], ColBegHor[IndexHor[1]], RowEndHor[IndexHor[1]], ColEndHor[IndexHor[1]], RowBegVer[IndexVer[0]], ColBegVer[IndexVer[0]], RowEndVer[IndexVer[0]], ColEndVer[IndexVer[0]], RowLL, ColLL, IsOverlapping)
    intersection_lines (RowBegHor[IndexHor[1]], ColBegHor[IndexHor[1]], RowEndHor[IndexHor[1]], ColEndHor[IndexHor[1]], RowBegVer[IndexVer[1]], ColBegVer[IndexVer[1]], RowEndVer[IndexVer[1]], ColEndVer[IndexVer[1]], RowLR, ColLR, IsOverlapping)
  • For visualization, we generate a contour that represents the fitted
  • quadrilateral, i.e., the field border.
    gen_contour_polygon_xld (FieldBorder, [RowUL,RowUR,RowLR,RowLL,RowUL], [ColUL,ColUR,ColLR,ColLL,ColUL])
    dev_display (Image)
    dev_display (FieldBorder)
    disp_message (WindowHandle, ‘Fitted field borders (quadrilateral)’, ‘image’, -1, -1, ‘black’, ‘true’)
    disp_continue_message (WindowHandle, ‘black’, ‘true’)
    stop ()
  • Now we can determine a projective transformation that will map our extracted
  • quadrilateral to a rectangle of given dimensions. Note that we have to
  • add 0.5 to the coordinates to make the extracted pixel positions fit the
  • coordinate system that is used by perspective_trans_image.
    vector_to_proj_hom_mat2d ([RowUL,RowUR,RowLR,RowLL] + 0.5, [ColUL,ColUR,ColLR,ColLL] + 0.5, [160,160,340,340] + 0.5, [250,550,550,250] + 0.5, ‘normalized_dlt’, [], [], [], [], [], [], HomMat2D, Covariance)
  • Note that we could also use the following call to determine the transformation:
  • hom_vector_to_proj_hom_mat2d ([RowUL,RowUR,RowLR,RowLL] + 0.5, [ColUL,ColUR,ColLR,ColLL] + 0.5, [1,1,1,1], [160,160,340,340] + 0.5, [250,550,550,250] + 0.5, [1,1,1,1], ‘normalized_dlt’, HomMat2D)
  • Now we can map the image and the quadrilateral.
    projective_trans_image_size (Image, TransImage, HomMat2D, ‘bilinear’, 800, 500, ‘false’)
    projective_trans_contour_xld (FieldBorder, FieldBorderTrans, HomMat2D)
    dev_set_window_extents (-1, -1, 800, 500)
    dev_display (TransImage)
    dev_display (FieldBorderTrans)
    disp_message (WindowHandle, ‘Rectified track and field:’, ‘image’, 20, 10, ‘black’, ‘true’)
    disp_message (WindowHandle, ‘virtual overhead view’, ‘image’, 45, 10, ‘black’, ‘true’)

在这里插入图片描述

在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

胖子工作室

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值