勇哥的视觉实验:GMM分类器(五) Novelty Detection(新奇检测)

前言:

==========================================================

分类器相对于深度学习来讲是一种古老传统的图片处理技术。halcon中常见的有四类分类器:

  • MLP(多层神经网络neural Nets)

  • SVM(支持向量机)

  • K-NN(K-最邻近)

  • GMM(高斯混合类型)

分类器的应用领域主要是下面这些:

  • image segmentation         图像分割  

  • object recognition             对象识别 

  • quality control                 质量控制

  • novelty detection             缺陷检测 

  • optical character recognition(OCR)      光学字符识别

勇哥第一次见到分类器的视觉项目是锂电池的极片缺陷检测,效果还不错。
这两年深度学习火起来后,发现深度学习完成上面所说的领域的应用更容易,效果也更好。

但深度学习对硬件要求太高,你把IPC加装个一百多W的显卡很多时候是不现实的。
如果你用cpu来跑,会发现速度乎快乎慢,cpu全部内核会100%被占用。
分类器相对于深度学习来讲不吃硬件,所以相对来讲算是轻量级的应用。

==========================================================

新奇检测Novelty Detection

大多数数据挖掘或数据工作中,异常值都会在数据的预处理过程中被认为是“噪音”而剔除,
以避免其对总体数据评估和分析挖掘的影响。
但某些情况下,如果数据工作的目标就是围绕异常值,那么这些异常值会成为数据工作的焦点。
数据集中的异常数据通常被成为异常点、离群点或孤立点等,
典型特征是这些数据的特征或规则与大多数数据不一致,
呈现出“异常”的特点,而检测这些数据的方法被称为异常检测。

[“噪音”的出现有多种原因,例如业务操作的影响(典型案例如网站广告费用增加10倍,导致流量激增)、
数据采集问题(典型案例如数据缺失、不全、溢出、格式匹配等问题)、数据同步问题
(异构数据库同步过程中的丢失、连接错误等导致的数据异常),而对离群点进行挖掘分析之前,
需要从中区分出真正的“离群数据”,而非“垃圾数据”。]

常用的异常检测方法可分为以下几类:

(一)基于统计的异常检测方法。

该方法的基本步骤是对数据点进行建模,再以假定的模型(如泊松分布、正太分布等)
根据点的分布来确定是否异常。
这种方法首先需要对数据的分布有所了解,进而通过数据变异指标来发现异常数据。
常用变异指标有极差、四分位数间距、均差、标准差、变异系数等。
但是,基于统计的方法检测出来的异常点产生机制可能不唯一,
而且它在很大程度上依赖于待挖掘的数据集是否满足某种概率分布模型,另外模型的参数、
离群点的数目等都非常重要,
确定这些因素通常都比较困难。因此,实际情况中算法的应用性和可移植性较差。

(二)基于距离的异常检测方法。
该方法定义包含并拓展了基于统计的思想,即使数据集不满足任何特定分布模型,它仍能有效地发现离群点,
特别是当空间维数比较高时,算法的效率比基于密度的方法要高得多 。
算法具体实现时,首先给出记录数据点间的距离(如 曼哈顿距离 、欧氏距离等),
然后对数据进行一定的预处理以后就可以根据距离的定义来检测异常值。
如基于K-Means的聚类可以将离每个类中心点最远或者不属于任何一个类的数据点提取出来而发现异常值。
基于距离的离群检测方法不需要用户拥有任何领域知识且具有比较直观的意义,算法比较容易理解,
因此在实际中应用得比较多。

(三)基于密度的离群检测方法。
这种方法一般都建立在距离的基础上,其主要思想是将数据点之间的距离和某一范围内数据数这两个参数结合起来,
从而得到“密度”的概念,然后根据密度判定记录是否为离群点。
例如LOF(局部异常因子)就是用于识别基于密度的局部异常值的算法。
离群点被定义为相对于全局的局部离群点,这与传统异常点的定义不同,异常点不再是一个二值属性
(要么是异常点,要么是正常点,实际上的定义类似于98%的可能性是一个异常点),
它摈弃了以前所有的异常定义中非此即彼的绝对异常观念,更加符合现实生活中的应用;
但其缺点就是它只对数值数据有效。

(四)基于偏移的异常点检测方法。
基于偏移的离群检测算法 (Deviation-based Outlier Detection) 
通过对测试数据集主要特征的检验来发现离群点。
目前,基于偏移的检测算法大多都停留在理论研究上,实际应用比较少。


(五)基于时间序列的异常点监测方法。
所谓时间序列就是将某一指标在不同时间上的数值,按照时间先后顺序排序而成的数列。
这种数列虽然由于受到各种偶然因素的影响而表现出某种随机性,不可能完全准确地用历史值来预测将来,
但是前后时刻的数值或数据点的相关性往往呈现某种趋势性或周期性变化,这是时间序列挖掘的可行性之所在。
时间序列中没有具体描述被研究现象与其影响因素之间的关系,而是把各影响因素分别看作一种作用力,
被研究对象的时间序列则看成合力;然后按作用特点和影响效果将影响因素规为 4 类,
即趋势变动( T )、季节变动( S )、循环变动( C )和随机变动( I )。
这四种类项的变动叠加在一起,形成了实际观测到的时间序列,
因而可以通过对这四种变动形式的考察来研究时间系列的变动。
目前国际和国内对时间序列相似度的研究提出了许多种解决方法,这些方法主要包括基于直接距离、傅立叶变换、 
ARMA 模型参数法、规范变换、时间弯曲模型、界标模型、神经网络、小波变换、规则推导等。 
关于时间序列的异常检测应用案例,
可参照《统计学在点击流数据中的应用范例——Adobe Analytics异常检测》
http://www.searchmarketingart.com/adobe-analytics-anomaly-detection.html

异常检测根据原始数据集的不同可分为两类:
新奇检测(Novelty Detection):新奇检测的前提是已知训练数据集是“纯净”的,
未被真正的“噪音”数据或真实的“离群点”污染,
然后针对这些数据训练完成之后再对新的数据进行训练以寻找异常数据。

离群点检测(Outlier Detection):离群点检测的训练数据集则包含“离群点”数据,
对这些数据训练完成之后再在新的数据集中寻找异常数据


官方例子:

这个示例程序向您展示了如何使用用于新奇检测的GMM分类器来执行网格检查任务。进行新奇性检测,

计算属于单个训练类的所有像素,然后从分类ROI中减去这些像素以提取错误像素。对于网格检测任务,GMM可以用来检测与训练好的物体的纹理不一致的纹理。

dev_update_off ()
* 
ReadPretrainedClassifier := false
* Uncomment the following line to read the pretrained classifier from
* disk. The training may last up to half a minute.
* ReadPretrainedClassifier := true
SaveClassifier := false
* Uncomment the following line to write the GMM classifier to disk after training.
* SaveClassifier := true
* 
read_image (Image, 'plastic_mesh/plastic_mesh_01')
get_image_size (Image, Width, Height)
dev_close_window ()
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
dev_set_color ('red')
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
get_system ('example_dir', HalconExamples)
*用于分类的纹理过滤器将返回图像边界处的瑕疵,因为要检查的塑料网格的图像不包含整数个网格单元。
*由于这会导致在图像边界处检测出错误,因此必须将靠近图像边界的区域排除在训练和分类之外。
*这是通过以下算子gen_rectangle1完成的。请注意,图像稍后会缩小两倍。
gen_rectangle1 (Rectangle, 10, 10, Height / 2 - 11, Width / 2 - 11)
if (ReadPretrainedClassifier)
    * 从磁盘读取预训练分类器.
    dev_display (Image)
    disp_message (WindowHandle, 'Reading classifier from disk...', 'window', 10, 10, 'black', 'true')
    read_class_gmm (HalconExamples + '/hdevelop/Segmentation/Classification/novelty_detection.gmm', GMMHandle)
    wait_seconds (1.5)
else
    
    create_class_gmm (5, 1, [1,5], 'spherical', 'normalization', 5, 42, GMMHandle)
    * 训练是基于五幅没有错误的图像.
    for J := 1 to 5 by 1
        read_image (Image, 'plastic_mesh/plastic_mesh_' + J$'02')
        *因为网格的分辨率非常高,所以图像被缩小了。这样可以节省大量的处理时间。
        zoom_image_factor (Image, ImageZoomed, 0.5, 0.5, 'constant')
        dev_display (ImageZoomed)
        disp_message (WindowHandle, 'Adding training samples...', 'window', 10, 10, 'black', 'true')
        * 生成纹理图像.
        gen_texture_image (ImageZoomed, ImageTexture)
        add_samples_image_class_gmm (ImageTexture, Rectangle, GMMHandle, 2.0)
    endfor
    dev_display (ImageZoomed)
    disp_message (WindowHandle, 'Training GMM...', 'window', 10, 10, 'black', 'true')
    train_class_gmm (GMMHandle, 100, 0.1, 'training', 0.0001, Centers, Iter)
    if (SaveClassifier)
        write_class_gmm (GMMHandle, HalconExamples + '/hdevelop/Segmentation/Classification/novelty_detection.gmm')
    endif
endif
* 现在检测塑料网格中的错误.
dev_set_draw ('margin')
dev_set_line_width (3)
for J := 1 to 14 by 1
    read_image (Image, 'plastic_mesh/plastic_mesh_' + J$'02')
    zoom_image_factor (Image, ImageZoomed, 0.5, 0.5, 'constant')
    dev_display (ImageZoomed)
    dev_set_color ('white')
    dev_display (Rectangle)
    gen_texture_image (ImageZoomed, ImageTexture)
    reduce_domain (ImageTexture, Rectangle, ImageTextureReduced)
    * 用GMM对训练类样本进行分类.
    classify_image_class_gmm (ImageTextureReduced, Correct, GMMHandle, 0.000002)
    * 从ROI中减去它们以获得纹理错误.
    difference (Rectangle, Correct, Errors)
    * 对返回的原始错误进行后处理,以删除检测到的错误中不重要的部分
    opening_circle (Errors, ErrorsOpening, 3.5)
    closing_circle (ErrorsOpening, ErrorsClosing, 10.5)
    connection (ErrorsClosing, ErrorsConnected)
    select_shape (ErrorsConnected, FinalErrors, 'area', 'and', 300, 1000000)
    count_obj (FinalErrors, NumErrors)
    dev_set_color ('red')
    dev_display (FinalErrors)
    if (NumErrors > 0)
        disp_message (WindowHandle, 'Mesh not OK', 'window', 10, 10, 'red', 'true')
    else
        disp_message (WindowHandle, 'Mesh OK', 'window', 10, 10, 'forest green', 'true')
    endif
    if (J < 14)
        disp_continue_message (WindowHandle, 'black', 'true')
    endif
    stop ()
endfor

本地函数gen_texture_image()

C#
*纹理图像是一个五通道图像,它包含五个不同的Laws滤波器的结果,
*这些滤波器基本上对应于一阶导数和二阶导数,并对它们进行充分的平滑处理。
texture_laws (Image, ImageEL, 'el', 5, 5)
texture_laws (Image, ImageLE, 'le', 5, 5)
texture_laws (Image, ImageES, 'es', 1, 5)
texture_laws (Image, ImageSE, 'se', 1, 5)
texture_laws (Image, ImageEE, 'ee', 2, 5)
compose5 (ImageEL, ImageLE, ImageES, ImageSE, ImageEE, ImageLaws)
smooth_image (ImageLaws, ImageTexture, 'gauss', 5)
return ()


检测效果如下图:

image.png



--------------------- 

作者:hackpig
来源:
www.skcircle.com
版权声明:本文为博主原创文章,转载请附上博文链接!



本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

会员中心
搜索
«    2024年3月    »
123
45678910
11121314151617
18192021222324
25262728293031
网站分类
标签列表
最新留言
    热门文章 | 热评文章 | 随机文章
文章归档
友情链接
  • 订阅本站的 RSS 2.0 新闻聚合
  • 扫描加本站机器视觉QQ群,验证答案为:halcon勇哥的机器视觉
  • 点击查阅微信群二维码
  • 扫描加勇哥的非标自动化群,验证答案:C#/C++/VB勇哥的非标自动化群
  • 扫描加站长微信:站长微信:abc496103864
  • 扫描加站长QQ:
  • 扫描赞赏本站:
  • 留言板:

Powered By Z-BlogPHP 1.7.2

Copyright Your skcircle.com Rights Reserved.

鄂ICP备18008319号


站长QQ:496103864 微信:abc496103864