这个例子其实是在比较两种ROI“还原”的方式;
模板匹配后,获得仿射变换矩阵T,则对于ROI的分析有两种:
1.全局的,将T.inv()*Img_target得到目标图片全局还原后的图片,在利用Region_Template,进行后续计算;
2.局部的,将T*Region_Template再对区域进行还原;
方法一计算量更大,但是Src简单,
* This example program shows how to rectify an image based on the matching
* results. The task is to extract and rectify the serial number on CDs.
* The recitification and extraction is shown in two different ways.
* In the first approach the full search image is rectified and then
* the numbers are extracted.
* In the second approach only the region of the numbers is rectified
* before the numbers are extracted.
*
*
dev_update_off ()
dev_close_window ()
*
* Read the model image and set visualization settings
read_image (ModelImage, 'cd_cover/cd_cover_01.png')
get_image_size (ModelImage, Width, Height)
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
dev_set_draw ('margin')
dev_set_line_width (2)
dev_display (ModelImage)
disp_message (WindowHandle, 'Model image', 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*
* Define the ROIs
* ---------------
* Select the ROI of the model object
Row1 := 96
Row2 := 149
Column1 := 87
Column2 := 179
gen_rectangle1 (ModelROI, Row1, Column1, Row2, Column2)
area_center (ModelROI, Area, CenterModelROIRow, CenterModelROIColumn)
dev_set_color ('blue')
dev_display (ModelROI)
disp_message (WindowHandle, 'ROI of the model', 'window', 40, 12, 'blue', 'true')
*
* Define the ROI of the numbers relative to the model object
gen_rectangle1 (NumberROI, Row2, Column1, Row2 + 30, Column2)
dev_set_color ('magenta')
dev_display (NumberROI)
disp_message (WindowHandle, 'ROI of the numbers', 'window', 60, 12, 'magenta', 'true')
stop ()
*
* Create the shape model
* -----------------------------------------------
reduce_domain (ModelImage, ModelROI, ImageReduced)
create_shape_model (ImageReduced, 4, 0, rad(360), 'auto', 'none', 'use_polarity', 30, 10, ModelID)
inspect_shape_model (ImageReduced, ShapeModelImage, ShapeModelRegion, 1, 50)
get_shape_model_contours (ShapeModel, ModelID, 1)
*
* Display the model contours
dev_set_color ('blue')
dev_set_line_width (1)
dev_display (ModelImage)
dev_display (ShapeModelRegion)
disp_message (WindowHandle, 'Model image', 'window', 12, 12, 'black', 'true')
disp_message (WindowHandle, 'Shape model', 'window', 40, 12, 'blue', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*
* Display description
dev_clear_window ()
Message := 'The shape model has been successfully created.'
Message[1] := 'In the next step each image is searched for the'
Message[2] := 'best match of the shape model followed by a'
Message[3] := 'rectification based on the matching results'
Message[4] := 'and the extraction of the numbers.'
Message[5] := ' '
Message[6] := 'The rectification is demonstrated in two'
Message[7] := 'different ways:'
Message[8] := '- rectification of the full search image'
Message[9] := '- rectification of only the ROI of the numbers'
disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*
* Find the object in each image and rectify the results
ImageFiles := 'cd_cover/cd_cover_'
for I := 1 to 4 by 1
dev_set_line_width (1)
*
* Read the search image and search the best
* match of the shape model in the search image
read_image (SearchImage, ImageFiles + I$'.2d')
find_shape_model (SearchImage, ModelID, 0, rad(360), 0.7, 1, 0.5, 'least_squares', 0, 1, RowMatch, ColumnMatch, AngleMatch, Score)
*
* If a match was found, rectify the results
if (|Score| > 0)
*
* Compute two affine transformations based on the position
* of the new match:
* --------------------------------------------------------
* 'MovementOfModel' for the shape model and
* 'MovementOfObject' for the rectification of the numbers
vector_angle_to_rigid (0, 0, 0, RowMatch, ColumnMatch, AngleMatch, MovementOfModel)
vector_angle_to_rigid (CenterModelROIRow, CenterModelROIColumn, 0, RowMatch, ColumnMatch, AngleMatch, MovementOfObject)
*
* Apply both affine transformations:
* --------------------------------------------------------
* one to the XLD contours of the shape model and
* one to the ROI of the numbers
affine_trans_contour_xld (ShapeModel, ModelAtNewPosition, MovementOfModel)
affine_trans_region (NumberROI, NumberROIAtNewPosition, MovementOfObject, 'nearest_neighbor')
*
* Display the model ROI and the ROI of the numbers at the (new)
* position in which the match was found in the current search image
dev_display (SearchImage)
dev_set_color ('blue')
dev_display (ModelAtNewPosition)
dev_set_color ('magenta')
dev_set_line_width (2)
dev_display (NumberROIAtNewPosition)
disp_message (WindowHandle, 'Search image ' + I, 'window', 12, 12, 'black', 'true')
disp_message (WindowHandle, 'Found match', 'window', 40, 12, 'blue', 'true')
disp_message (WindowHandle, 'ROI of the numbers', 'window', 60, 12, 'magenta', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*
* Approach 1: Rectification of the full search image
* **********************************************************
* First the full search image is rectified. Then the numbers
* are extracted.
* **********************************************************
*
* Step 1: Rectify search image
* ----------------------------
* Invert the transformation matrix 'MovementOfObject' computed
* for the rectification of the numbers so it can be used for the
* rectification of the full search image
hom_mat2d_invert (MovementOfObject, InverseMovementOfObject)
affine_trans_image (SearchImage, RectifiedSearchImage, InverseMovementOfObject, 'constant', 'false')
*
* Display the rectified search image and the ROI of the numbers
dev_clear_window ()
dev_display (RectifiedSearchImage)
dev_display (NumberROI)
disp_message (WindowHandle, '1. Approach: Rectified search image ' + I, 'window', 12, 12, 'black', 'true')
disp_message (WindowHandle, 'ROI of the numbers', 'window', 40, 12, 'magenta', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*
* Step 2: Extract the numbers
* ---------------------------
* Reduce the domain of the rectified image to the region of the
* numbers and extract the numbers using a global gray value treshold
reduce_domain (RectifiedSearchImage, NumberROI, RectifiedNumberROIImage)
threshold (RectifiedNumberROIImage, Numbers, 0, 128)
connection (Numbers, IndividualNumbers)
*
* Display the extracted numbers in the reduced rectified image
dev_set_colored (12)
dev_set_draw ('fill')
dev_display (IndividualNumbers)
disp_message (WindowHandle, 'Extracted numbers', 'window', CenterModelROIRow, Column1 - 50, 'black', 'true')
stop ()
*
* Approach 2: Rectify only the number ROI
* ***********************************************************
* In this approach the search image is first cropped to the
* region of the numbers. The new cropped search image is then
* rectified and the numbers are extracted.
* ***********************************************************
*
* Display the original search image (no rectification) and
* the corresponding ROI of the numbers
dev_set_draw ('margin')
dev_set_color ('magenta')
dev_display (SearchImage)
dev_display (NumberROIAtNewPosition)
*
* Step 1: Crop the search image
* -----------------------------
* Compute the smallest rectangle surrounding the ROI
* of the numbers parallel to the coordinate axes
smallest_rectangle1 (NumberROIAtNewPosition, RowRect1, ColumnRect1, RowRect2, ColumnRect2)
dev_set_color ('lime green')
disp_rectangle1 (WindowHandle, RowRect1, ColumnRect1, RowRect2, ColumnRect2)
disp_message (WindowHandle, '2. Approach: Crop search image ' + I, 'window', 12, 12, 'black', 'true')
disp_message (WindowHandle, 'ROI of the numbers', 'window', 40, 12, 'magenta', 'true')
*
* Crop the image to the determined rectangle around the numbers
crop_rectangle1 (SearchImage, CroppedSearchImage, RowRect1, ColumnRect1, RowRect2, ColumnRect2)
*
* Open a new window displaying the cropped image of the numbers
Width2 := ColumnRect2 - ColumnRect1 + 1
Height2 := RowRect2 - RowRect1 + 1
dev_open_window (0, Width + 10, Width2, Height2, 'black', CroppedWindowHandle)
dev_set_part (0, 0, Height2 - 1, Width2 - 1)
dev_display (CroppedSearchImage)
disp_rectangle1 (CroppedWindowHandle, 0, 0, Height2, Width2)
*
* Display the corresponding message
Message := 'Cropped image part'
Message[1] := '(See also the upper right window)'
disp_message (WindowHandle, Message, 'window', 65, 12, 'lime green', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*
* Step 2: Rectifiy the cropped search image
* ------------------------------------------
* Prepare the transformation matrix needed for the
* rectification. Add the translation of the cropping to
* the transformation matrix and then invert the matrix.
hom_mat2d_translate (MovementOfObject, -RowRect1, -ColumnRect1, MoveAndCrop)
hom_mat2d_invert (MoveAndCrop, InverseMoveAndCrop)
*
* Rectify the cropped search image using the
* inverted transformation matrix
affine_trans_image (CroppedSearchImage, RectifiedROIImage, InverseMoveAndCrop, 'constant', 'true')
*
* Display the rectified cropped search image in a new window
get_image_size (RectifiedROIImage, Width3, Height3)
dev_set_part (0, 0, Height3 - 1, Width3 - 1)
dev_open_window (Height2 + 60, Width + 10, Width3, Height3, 'black', WindowHandle1)
set_display_font (WindowHandle1, 11, 'mono', 'true', 'false')
dev_clear_window ()
dev_display (RectifiedROIImage)
disp_message (WindowHandle1, 'Rectified cropped image', 'window', 5, 5, 'black', 'true')
stop ()
*
* Step 3: Extract the numbers
* ---------------------------
* Reduce the domain of the rectified and cropped image to the region of
* the numbers and extract the numbers using a global gray value treshold
reduce_domain (RectifiedROIImage, NumberROI, RectifiedNumberROIImage)
threshold (RectifiedNumberROIImage, Numbers, 0, 128)
connection (Numbers, IndividualNumbers)
dev_clear_window ()
dev_display (RectifiedNumberROIImage)
dev_set_colored (12)
dev_set_draw ('fill')
dev_display (IndividualNumbers)
disp_message (WindowHandle1, 'Extracted numbers', 'window', 5, 5, 'black', 'true')
stop ()
endif
if (I < 4)
dev_set_window (CroppedWindowHandle)
dev_close_window ()
dev_set_window (WindowHandle1)
dev_close_window ()
endif
endfor
disp_end_of_program_message (WindowHandle, 'black', 'true')
*
* Clear the model
clear_shape_model (ModelID)