cbm_caliper

* This example shows how to use the component-based matching in order
* to locate all instances of a caliper that consists of two components  in
* a perspectively distorted image. The relative movements (relations)
* are automatically trained by using only one training image. After
* creating the component model the caliper is found in a run-time image
* Finally, the measure of the caliper is calculated.
dev_update_off ()
dev_set_draw ('margin')
dev_set_line_width (2)
read_image (ModelImage, 'caliper/caliper_model')
get_image_size (ModelImage, Width, Height)
dev_close_window ()
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
set_display_font (WindowHandle, 14, 'mono', 'true', 'false')
* Perform the camera calibration
CalTabDescrFile := 'caltab_30mm.descr'
gen_cam_par_area_scan_division (0.0085, 0, 0.0000073, 0.0000073, Width / 2, Height / 2, Width, Height, StartCamPar)
create_calib_data ('calibration_object', 1, 1, CalibDataID)
set_calib_data_cam_param (CalibDataID, 0, [], StartCamPar)
set_calib_data_calib_object (CalibDataID, 0, CalTabDescrFile)
NumImages := 13
for I := 1 to NumImages by 1
    read_image (Image, 'caliper/caliper_calib_' + I$'02d')
    dev_display (Image)
    Message := 'Find calibration plate in\nall calibration images (' + I + '/' + NumImages + ')'
    disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
    * Find the calibration plate
    find_calib_object (Image, CalibDataID, 0, 0, I - 1, [], [])
    get_calib_data (CalibDataID, 'camera', 0, 'init_params', StartCamPar)
    get_calib_data_observ_points (CalibDataID, 0, 0, I - 1, Row, Column, Index, Pose)
    get_calib_data_observ_contours (Contours, CalibDataID, 'caltab', 0, 0, I - 1)
    gen_cross_contour_xld (Cross, Row, Column, 6, 0.785398)
    dev_set_color ('green')
    dev_display (Contours)
    dev_set_color ('yellow')
    dev_display (Cross)
endfor
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
calibrate_cameras (CalibDataID, Error)
get_calib_data (CalibDataID, 'camera', 0, 'params', CamParam)
* The pose of the calibration target in the first image defines a plane that is
* parallel to the plane in which the objects lie.  This pose can be used to see how
* much the camera is rotated with respect to this plane.
get_calib_data (CalibDataID, 'calib_obj_pose', [0,0], 'pose', PoseCalib)
* Since the orientation of the calibration target in the first image is wrong by
* -90 degrees we apply a rotation of 90 degrees around the z axis.
PoseCalibRot := replace(PoseCalib,5,PoseCalib[5] + 90)
* The pose of the calibration target in the first image defines a plane that is offset
* from the plane in which the objects lie by the thickness of the calibration target.
* Therefore, we need to shift the origin of the pose in the z direction by the
* thickness. Note that the thickness of the calibration target used for this
* example is 0.63 mm. If you adapt this example program to your application, it
* is necessary to determine the thickness of your specific calibration target and to
* use this value instead. Furthermore, we need to shift the origin so that the top left corner
* of the image lies approximately in the top left corner of the rectified image.
set_origin_pose (PoseCalibRot, -0.082, -0.04, 0.00063, Pose)
* We also need to define the pixel spacing in the rectified image.  In this case,
* we set it to 0.2mm (i.e., 0.0002m).
PixelDist := 0.0002
* We also compute the transformation from the world coordinate system, i.e., the
* coordinate system of the plane, to the camera coordinate system.  This
* transformation is later used to visualize the recognized objects in the distorted
* (i.e., original, unrectified) images.
pose_to_hom_mat3d (Pose, HomMat3D)
* We now can compute the mapping function to rectify the image because it does
* not change (the camera does not move with respect to the world plane).
WidthMapped := 785
HeightMapped := 575
gen_image_to_world_plane_map (Map, CamParam, Pose, Width, Height, WidthMapped, HeightMapped, PixelDist, 'bilinear')
dev_set_window_extents (-1, -1, WidthMapped, HeightMapped)
* Train the model components
map_image (ModelImage, Map, ModelImageMapped)
* Define the initial components
gen_rectangle2 (InitialComponents, 164, 283, 1.23, 75, 36)
gen_rectangle2 (InitialComponent, 233, 432, 1.21, 87, 45)
concat_obj (InitialComponents, InitialComponent, InitialComponents)
dev_set_colored (12)
dev_clear_window ()
dev_display (ModelImageMapped)
dev_display (InitialComponents)
Message := 'Rectified model image and'
Message[1] := 'input regions describing the initial components'
disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
* Get the trainings image
read_image (TrainingImage, 'caliper/caliper_training_1')
map_image (TrainingImage, Map, TrainingImageMapped)
dev_clear_window ()
dev_display (TrainingImageMapped)
disp_message (WindowHandle, 'Mapped training image', 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* The component-based matching uses the contours of the components
* as features for the matching. In order to make sure that only significant
* features are involved in the matching the parameters ContrastLow,
* ContrastHigh, and MinSize can be passed to the training. To inspect the
* effect of different values for these three parameters, and hence to find
* the optimum values for a certain application, the following two lines of
* code can be used:
* add_channels (InitialComponents, ModelImageMapped, ModelImageInitComp)
* gen_initial_components (ModelImageInitComp, InitialComponentsEdges, 30, 30, 20, 'connection', [], [])
* Extract the model components and train the relations
dev_clear_window ()
dev_display (ModelImageMapped)
Message := 'Train the model components ...'
disp_message (WindowHandle, 'Train the model components...', 'window', 12, 12, 'black', 'true')
train_model_components (ModelImageMapped, InitialComponents, TrainingImageMapped, ModelComponents, 30, 30, 20, 0.8, -1, -1, rad(40), 'speed', 'rigidity', 0.2, 0.5, ComponentTrainingID)
Message := 'Train the model components ... ready'
Message[1] := 'Results:'
Message[2] := '  1) Final model components'
disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
dev_set_colored (12)
get_training_components (ModelComponents, ComponentTrainingID, 'model_components', 'model_image', 'false', RowRef, ColumnRef, AngleRef, ScoreRef)
DeltaRow := RowRef[1] - RowRef[1]
DeltaCol := ColumnRef[1] - ColumnRef[0]
DistanceRef := sqrt(DeltaRow * DeltaRow + DeltaCol * DeltaCol)
dev_display (ModelComponents)
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
count_obj (ModelComponents, NumComp)
dev_set_line_width (1)
for I := 0 to NumComp - 1 by 1
    dev_clear_window ()
    dev_display (ModelImageMapped)
    Message := [Message,'  ' + (2 + I) + ') Relations with respect to component ' + I]
    disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
    dev_set_colored (12)
    get_component_relations (Relations, ComponentTrainingID, I, 'model_image', Row, Column, Phi, Length1, Length2, AngleStart, AngleExtent)
    dev_display (Relations)
    disp_continue_message (WindowHandle, 'black', 'true')
    stop ()
endfor
* Add small tolerances to the automatically derived relations in order
* to receive a higher robustness.
modify_component_relations (ComponentTrainingID, 'all', 'all', 3, rad(2))
* Create the component model based on the training result.
create_trained_component_model (ComponentTrainingID, rad(-45), rad(90), 10, 0.5, 'auto', 'auto', 'none', 'use_polarity', 'false', ComponentModelID, RootRanking)
get_component_model_tree (Tree, Relations, ComponentModelID, 1, 'model_image', StartNode, EndNode, Row, Column, Phi, Length1, Length2, AngleStart, AngleExtent)
dev_clear_window ()
dev_display (ModelImageMapped)
disp_message (WindowHandle, 'Component model', 'window', 12, 12, 'black', 'true')
dev_set_colored (12)
dev_display (Tree)
dev_display (Relations)
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* For visualization purposes, we also create a contour that corresponds to the
* boundary of the object. This allows us to visualize the recognized models in
* the original images.
get_component_model_params (ComponentModelID, MinScoreComp, RootRanking, ShapeModelIDs)
get_shape_model_contours (Component0, ShapeModelIDs[0], 1)
get_shape_model_contours (Component1, ShapeModelIDs[1], 1)
* Find the component model in a run-time image
dev_set_window_extents (-1, -1, Width, Height)
dev_set_line_width (2)
Measure := [55.6,30.5,35.3,51.7,55.6]
ImgNo := 1
Button := 0
while (Button == 0)
    read_image (SearchImage, 'caliper/caliper_' + ImgNo)
    count_seconds (Seconds1)
    map_image (SearchImage, Map, SearchImageMapped)
    find_component_model (SearchImageMapped, ComponentModelID, RootRanking, -rad(20), rad(40), 0.7, 0, 1, 'stop_search', 'prune_branch', 'none', 0.5, 'least_squares_very_high', 0, 0.9, ModelStart, ModelEnd, Score, RowComp, ColumnComp, AngleComp, ScoreComp, ModelComp)
    count_seconds (Seconds2)
    NumFound := |ModelStart|
    Time := (Seconds2 - Seconds1) * 1000
    dev_display (SearchImage)
    for Match := 0 to |ModelStart| - 1 by 1
        get_found_component_model (FoundComponents, ComponentModelID, ModelStart, ModelEnd, RowComp, ColumnComp, AngleComp, ScoreComp, ModelComp, Match, 'false', RowCompInst, ColumnCompInst, AngleCompInst, ScoreCompInst)
        DeltaRow := RowCompInst[1] - RowCompInst[0]
        DeltaCol := ColumnCompInst[1] - ColumnCompInst[0]
        Distance := sqrt(DeltaRow * DeltaRow + DeltaCol * DeltaCol)
        ActualMeasure := Measure[ImgNo]
        MeasureFromPoses := ((Distance - DistanceRef) * PixelDist + 0.01661) * 1000
        * Project the first component from the world plane back into the original image.
        contour_world_to_image (Component0, ContourImage0, RowCompInst[0], ColumnCompInst[0], AngleCompInst[0], PixelDist, HomMat3D, CamParam)
        dev_set_color ('red')
        dev_display (ContourImage0)
        * Project the second component from the world plane back into the original image.
        contour_world_to_image (Component1, ContourImage1, RowCompInst[1], ColumnCompInst[1], AngleCompInst[1], PixelDist, HomMat3D, CamParam)
        dev_set_color ('green')
        dev_display (ContourImage1)
    endfor
    Message := 'Object found in ' + Time$'4.2f' + ' ms'
    Result := 'Actual Measure:     ' + Measure[ImgNo - 1]$'3.1f' + ' mm'
    Result[1] := 'Measure from Poses: ' + MeasureFromPoses$'3.1f' + ' mm'
    disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
    disp_message (WindowHandle, Result, 'window', 400, 300, 'black', 'true')
    disp_message (WindowHandle, 'Press mouse button to stop the demo', 'window', 450, 20, 'black', 'true')
    ImgNo := ImgNo + 1
    if (ImgNo > 4)
        ImgNo := 1
    endif
    dev_error_var (Error, 1)
    dev_set_check ('~give_error')
    get_mposition (WindowHandle, R, C, Button)
    dev_error_var (Error, 0)
    dev_set_check ('give_error')
    if (Error != H_MSG_TRUE)
        Button := 0
    endif
endwhile

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

electrical1024

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

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

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

打赏作者

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

抵扣说明:

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

余额充值