Blob分析之check_blister_mixed.hdev

* 本例展示了制药行业的应用。目是检测出人工放置的水泡(姑且这么叫)中的药片/胶囊的内容
*第一张图片是要求的组合,后续的图像检测中以此为参考,我们用在程序开始的时候就用参考图像训练好的GMM分类器
*来对后续的图像中的药片进行识别分类
*(看上去英语是一大段话,还有各种从句啥的,翻译过来就这么点东西)

*This example demonstrates an application from the pharmaceutical
* industry. The task is to check the content of manually filled
* blisters. The first image (reference) shows the combination, that
* is requested. The subsequent images are then checked for this
* setup drawn from the reference image. To perform this task we use
* the gmm classifier, which will be trained with the reference image
* in the beginning and is then used to classify the different pill
* types in subsequent blister images.
*
*关闭窗体
dev_close_window ()
*读取图像
read_image (Image, 'blister/blister_mixed_reference')
*打开适合图像大小的图像
dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)
*设置显示字体
set_display_font (WindowHandle, 14, 'mono', 'true', 'false')
*关闭更新
dev_update_off ()
*显示图像
dev_display (Image)
*设置填充方式
dev_set_draw ('margin')
* 第一,把水泡包装壳里面的内容提取出来,把这个信息给Gmm分类器
* First, we extract the content of the blister and pass
* this information on to the gmm classifier
*显示信息
disp_message (WindowHandle, 'Train gmm classifier on pill types', 'window', 12, 12, 'black', 'true')
*本地函数,主要是提取药片种类
extract_pill_types (Image, Chambers, ChambersUnion, Classes, PhiRef, RowRef, ColumnRef, PillTypeCount)
*定义分类器的类数量
NumClasses := |PillTypeCount|
*创建GMM句柄
create_class_gmm (3, 3, [1,5], 'spherical', 'normalization', 10, 42, GMMHandle)
*添加样本到GMM类
add_samples_image_class_gmm (Image, Classes, GMMHandle, 0)
*训练GMM类
train_class_gmm (GMMHandle, 100, 0.001, 'training', 0.0001, Centers, Iter)
* 以上就是训练gmm 分类器
*以下就应该是提取识别了
* 测试后续图像是否正确分类正确
* Then, the subsequent blisters are tested for their right combination
Count := 12
for FileIndex := 1 to Count by 1
    * 把当前图像与参考图像对齐
    * Align image read
    *读取图像
    read_image (Image, 'blister/blister_mixed_' + FileIndex$'02')
    *阈值分割
    threshold (Image, Region, 90, 255)
    *联通区域
    connection (Region, ConnectedRegions)
    *更根据面积选择形状
    select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 5000, 9999999)
    *变换选中的图像
    shape_trans (SelectedRegions, RegionTrans, 'convex')
    *求区域与极轴的夹角
    orientation_region (RegionTrans, Phi)
    *
    if (abs(Phi) > rad(90))
        Phi := rad(180) + Phi
    endif
    *求取面积和中心坐标
    area_center (RegionTrans, Area1, Row, Column)
    *求取刚性变换矩阵--当前图像到参考图像
    vector_angle_to_rigid (Row, Column, Phi, RowRef, ColumnRef, PhiRef, HomMat2D)
    *把当前图像变换到参考图像位置
    affine_trans_image (Image, ImageAffineTrans, HomMat2D, 'constant', 'false')
    *截取区域
    reduce_domain (ImageAffineTrans, ChambersUnion, ImageReduced)
    *把多通道图像按通道分解成三幅图像(红,率,蓝)
    decompose3 (ImageAffineTrans, ImageR, ImageG, ImageB)
    * 用分类器进行分类
    * Classify pill type for each chamber
    classify_image_class_gmm (ImageReduced, ClassRegions, GMMHandle, 0.005)
    * 获取识别的有几种分类
    count_obj (ClassRegions, Number)
    *生成空对象
    gen_empty_obj (FinalClasses)
    *联通区域
    connection (Chambers, ChambersRemaining)
    *选择同一类别的区域
    for Index := Number to 1 by -1
        *清除窗体
        dev_clear_window ()
        *选择是识别的区域
        select_obj (ClassRegions, Region, Index)
        *求交集
        intersection (ChambersRemaining, Region, Region)
        *跟据面积和宽度选择形状
        select_shape (Region, PillsOfOneType, ['area','width'], 'and', [200,40], [3000,80])
        *求取区域差集
        difference (ChambersUnion, PillsOfOneType, RegionDifference)
        *联通区域
        connection (RegionDifference, ConnectedRegions)
        *根据面积选择形状
        select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 0, 7868)
        *变换形状
        shape_trans (SelectedRegions, SelectedRegions, 'convex')
        *联合区域
        union1 (SelectedRegions, SelectedRegions)
        *求差集
        difference (ChambersRemaining, SelectedRegions, ChambersRemaining)
        *联合区域,转换成最终想要的分类号的区域
        concat_obj (SelectedRegions, FinalClasses, FinalClasses)
    endfor
    *
    *
    * Check for right combination
    *分别生成丢失药片,错误药片,数量不对药片空对象
    gen_empty_obj (MissingPills)
    gen_empty_obj (WrongPills)
    gen_empty_obj (WrongNumberOfPills)
    *求区域差集
    difference (ChambersUnion, FinalClasses, LeftOvers)
    *求差集区域的面积和中心坐标
    area_center (LeftOvers, Area, Row1, Column1)
    *如果面积大于零,说明就有这个类的目标找到
    if (Area > 0)
        *联通区域
        connection (LeftOvers, LeftOvers)
        *求找到的类目标数量
        count_obj (LeftOvers, Number)
        *
        for Index := 1 to Number by 1
            select_obj (LeftOvers, ObjectSelected, Index)
            *求区域的平均灰度值和灰度方差
            intensity (ObjectSelected, ImageB, Mean, Deviation)
            *如果方差大于40则为错误药片,否则为丢失药片
            if (Deviation > 40)
                concat_obj (WrongPills, ObjectSelected, WrongPills)
            else
                concat_obj (MissingPills, ObjectSelected, MissingPills)
            endif
        endfor
    endif
    * 计算直方图
    * Compute histogram
    CountFinalClass := []
    *汇总所找到的目标。为后续显示用
    for Index := 1 to NumClasses by 1
        select_obj (FinalClasses, ObjectSelected, Index)
        connection (ObjectSelected, ObjectSelected)
        count_obj (ObjectSelected, Size)
        CountFinalClass := [CountFinalClass,Size]
    endfor
    * 显示分类结果和数据
    * Display classification results and output allover statistic
    display_results (ImageAffineTrans, LeftOvers, FinalClasses, WrongPills, CountFinalClass, PillTypeCount, WindowHandle)
    if (FileIndex < Count)
        *显示 'Press F5 to continue'这个信息
        disp_continue_message (WindowHandle, 'black', 'true')
    endif
    stop ()
endfor
*
* 清除分类句柄
* Clear classifier handle
clear_class_gmm (GMMHandle)

posted @ 2020-08-02 15:35  懒树懒  阅读(295)  评论(0)    收藏  举报