基于图像处理(HOG)与数据分布特征的水位识别

Update

代码已经上传到github上了,可以点这里


Cutting

一直说这要整理一下Computer Vision课程的大作业,拖了好久。这两天忙着写一个订单处理的第三方库,陷入了僵局,所以换个口味,把大作业整理一下。

Requirement

Water depth measurement.
实现目标:通过使用计算机视觉及图像处理技术,通过正确检测插入水体的标尺和水体水平面的刻度值来确定水位高度。图像数据见附件。
可允许用户输入标尺最上端的高度值、照相机镜头距离标尺最上端的和水平面形成的夹角、刻度尺正面和照相机之间夹角值,以及标尺每个刻度的高度值。

评分标准:

  1. 能否解决存在的多种问题,其中包括:
    a. 标尺刻度靠近水面的部分可能由于长期浸泡在污水中出现污渍而无法识别。
    b. 水面可能出现的雾气,造成识别困难。
    c. 标尺可能有一定的弧度,造成精确度量存在问题。
  2. 计算效率:使用任意目前流行的Intel i3处理器及更快的处理器,每个4096*4096像素分辨率以内的图像测量时间不超过20秒(包含图像读取及数据值输出)。
    3.系统完整性。

使用语言:Visual C++(可使用OpenCV)
部分附件

样例图

Train of Thought

整个过程大致分为四个阶段:图像预处理、识别、过滤、数据处理

1. 预处理

首先会进行一个直方图均衡化的操作。再由于输入的图像差别较大,有如上图这种十分清晰的,也存在模糊到人工识别也比较吃力的。所以显然不同的清晰度应该有不同的处理方式。这里简单的将清晰度分为清晰模糊两类。

对于清晰的图片,进行适度腐蚀膨胀操作,以进一步提高图片中标尺的对比度。

            //腐蚀、膨胀
            int erosion_size = 3;
            Mat element = getStructuringElement( MORPH_RECT,
                                                Size( 2*erosion_size + 1, 2*erosion_size+1 ),
                                                Point( erosion_size, erosion_size ) );
            /// 腐蚀操作
            erode( origin, origin, element );
            dilate(origin, origin, element);

对于模糊的图片数据,先进行滤波,再提高对比度

            //创建并初始化滤波模板
            cv::Mat kernel(3,3,CV_32F,cv::Scalar(0));
            kernel.at<float>(1,1) = 5.0;
            kernel.at<float>(0,1) = -1.0;
            kernel.at<float>(1,0) = -1.0;
            kernel.at<float>(1,2) = -1.0;
            kernel.at<float>(2,1) = -1.0;

            cv::filter2D(origin,origin,origin.depth(),kernel);
            
            int alpha = 1.5;
            int beta = 50;
            for( int y = 0; y < origin.rows; y++ )
            {
                for( int x = 0; x < origin.cols; x++ )
                {
                    for( int c = 0; c < 3; c++ )
                    {
                        origin.at<Vec3b>(y,x)[c] = saturate_cast<uchar>( alpha*( origin.at<Vec3b>(y,x)[c] ) + beta );
                    }
                }
            }

对比效果:


腐蚀膨胀

2. 识别

考查了Haar LikeSIFTLBPHOG等算法。Haar Like多用于人脸识别,LBP多用于基于纹理特征的监测,所以不是很适合。SIFT做了简单测试,识别效果如下:

SIFT识别效果

不是很理想,所以最后选定了HOG算法。

  • 训练素材准备
    由于检测的目标多位于水边,环境多为山、天空、水、泥土等,所以额外加入了这些素材作为负样本。由于负样本创建有一定规格要求,所以使用Python脚本,批量裁剪,最后共得到负样本42360个。
  • 训练识别过程
    这一过程网上有不少代码可供参考,主要是对于参数等选择比较重要。这里我们定义部分参数如下:
//识别与检测的参数
#define WIN_SIZE Size(64,64)
#define BLOCK_SIZE Size(8,8)
#define BLOCK_STRIDE Size(4,4)
#define CELL_SIZE Size(4,4)
#define BIN 12

2. 过滤

对于识别结果需要进行过滤。这里我们定义了一个Mask算法,用以合并多个过滤算法多结果。
对于每一种过滤算法,都会有各自的保留区域,将它们叠加,通过某个大小的矩形扫描,如果该矩形区域内,每一层的保留区域面积占比大于一个可调参数Threshold,则认为该矩形区域应该保留。

示意图

这里我们使用了两种过滤算法:

  • ColorFilter
    基于颜色特征的过滤。由于标尺上的颜色固定,故可以丢弃与之无关的颜色区域


    颜色过滤
  • Canny边缘检测过滤

    Canny算子多用于检测物体的边缘,我们通过保留边缘区域后,并将边缘铺展开来,以得到保留区域。
    边缘检测过滤

    最后运用上面提到的多层Mask合并算法,得到最终的过滤保留区域。
    Mask叠加

可以看到将过滤结果应用于识别结果时,大量的误识别被过滤掉了。原图非常大,绿色的框框即为识别结果。


  • 单峰过滤
    由于一张图中仅有一个标尺,所以通过前面的过滤后,我们认为,矩形在图片上的分布应该如图所示。将除最高峰以外的矩形丢弃。


  • Rectangle修正
    标尺中的"E"标示实际分布是均匀的,所以即使无法完全识别,也可以通过算法进行一个修正,自动补全出未被识别的"E"
    效果如下:


    修正效果

4. 数据处理

最后的处理是针对识别结果进行纯数值分析的优化。我们认为识别系统稳定后,会存在一定的固有误差,可以通过线性拟合的方式进行一个修正。将识别数据与真实数据进行拟合(这一点老师不是很赞成,认为没有必要)。


数据拟合

Closing

这个大作业感觉还是很有难度的,部分的结果识别还是比较满意的,但是也有一些图片是偏差蛮大的。而且由于是直接调用的OpenCV的库,实际上对图像处理的一些算法还是没有很深入,有机会再回来搞搞视觉吧。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,039评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,223评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,916评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,009评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,030评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,011评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,934评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,754评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,202评论 1 309
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,433评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,590评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,321评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,917评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,568评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,738评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,583评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,482评论 2 352

推荐阅读更多精彩内容

  • 不同图像灰度不同,边界处一般会有明显的边缘,利用此特征可以分割图像。需要说明的是:边缘和物体间的边界并不等同,边缘...
    大川无敌阅读 13,847评论 0 29
  • 知乎上看到一个话题——目前火热的 Deep Learning 会灭绝传统的 SIFT / SURF 特征提取方法吗...
    牛奶芝麻阅读 100,818评论 4 81
  • 计算机应用 2016,Vol. 36 Issue (11): 2979-2984,2992DOI:10.11772...
    wotacid阅读 7,243评论 0 2
  • 我走遍世上每个角落 只为寻找最美的树叶 然后 虔诚的 写上你的名字 再夹进我最爱的书籍 仿佛这样 才是永恒
    ivy_y阅读 149评论 0 0
  • 常听人说,十个胖子九个虚,这里的虚,就是脾虚。还有人说喝水都长胖,这个胖,也是脾虚不能运化水湿形成的痰湿。今天,和...
    郁茹阅读 2,218评论 0 1