[关闭]
@dragonfive 2015-08-30T00:54:02.000000Z 字数 3512 阅读 720

船只检测

专项中心工作


这篇博客有一定参考价值

第一步 获取样本

获取正样本

<1>爬虫下载原始图片

遇到的问题:每次晚上都会断网,爬虫程序需要重新跑,但是之前已经有下载过的程序了。
解决方案:这里我们每个船下载100张图片 看一下一共下载了多少张除以100 然后从列表中剔除前100个shipid;
点击见具体程序

<2>抠图

源码理解

1.两个demo貌似用了并行算法

裁剪的思路先剪出分辨率一样的东西。

两种办法

修改代码最少的办法:(运行时间可能比较长)
把每个图片的结界都算两遍
第一遍找出其中的最大值。
最后 第二遍计算然后调整用相同大小的框去框

可能运行效率高的办法:(使用空间比较多)
把每个图中船只的边界用数组保存
算出其中的值,然后就调整每个值,然后去框

过程如下:
1. 如果直接判断框如果在图像外面就判错,那么333个船里只能有4个船满足条件,并且四个船的姿势是一样的。
2. 调整算法之后误差大了 可以找到8个船。稍微移动框的位置
3. 基于已知条件原始图片的长是固定的,宽是不定的,所以我们选取最小的宽与maxRow对比确定maxLength
遇到一个问题就是:奇数与偶数问题。
4. 2000个样本总是会第一个demo运行过程中形成一个异常 使用1020个样本可行

<3>缩小图片的分辨率

  1. python图像处理需要使用python2.7 32位和opencv3.0 准备在ubuntu下面搞
  2. 调用南开大学的基本库,用c++语言做 相关代码如下
  1. void image_resize()
  2. {
  3. CStr sampleDir = wkDir + "Sample/";
  4. CStr resultDir = wkDir + "ResIlu/";
  5. /************************************************************************/
  6. /* 获取剪切后目录下的所有图片*/
  7. /************************************************************************/
  8. CStr search_path = resultDir + "*_RCC_Match_cut.jpg";
  9. vector<string> file_list;
  10. if (!get_filelist_from_dir(search_path, file_list))
  11. cout << "open file error!" << endl;
  12. /************************************************************************/
  13. /* 创建缩放后的目录*/
  14. /************************************************************************/
  15. CmFile::MkDir(sampleDir);
  16. /************************************************************************/
  17. /* 缩放*/
  18. /************************************************************************/
  19. double scale = 0.2; //设置缩放倍数
  20. for (int i = 0; i < file_list.size(); i++)
  21. {
  22. CStr image_path = resultDir + file_list[i];
  23. CStr resNameNE = CmFile::GetNameNE(image_path);
  24. Mat image = imread(image_path);
  25. Size dsize = Size(image.cols*scale, image.rows*scale);
  26. Mat image2 = Mat(dsize, CV_32S);
  27. resize(image, image2, dsize);
  28. imwrite(sampleDir + resNameNE + ".jpg", image2);
  29. cout << "完成第" << i + 1 << "个图片的缩放" << endl;
  30. }
  31. }

获取负样本

<1>下载pascal_voc

<2>pascal_voc图片解析

python脚本
现在的任务是重pascalvoc中找到不含boat的负样本 复制到一个文件夹里面去;
用的是c#读取xml文件。然后复制文件。
点击见具体程序

第二步 训练分类器

使用120个正样本,分辨率为57*18。 1044个负样本(提取自pascal_voc数据集)
相关参数为nsplits = 2, nstages = 10

第一阶段

5层分类器效果差
当训练到第5层的时候生成xml,进行船只检测,结果如下:
船只检测

船只二

船只三

第二阶段

10层分类器效果偶尔会好一点


第三阶段

采用1020个正样本,9599个负样本
test2.jpg
test2.jpg
test2.jpg
test2.jpg

第四阶段

获取海水信息作为负样本
挑选优质的正样本,并手动裁剪一些不好的样本
同时修正船只检测程序
解决自己训练的分类器速度慢的问题:已解决 这个跟训练的分类器的级别有关

2015年8月16日 10:48:14 更新
准备用同一个比例手动选取特定的图片,测试检测特定方向的船的效果是否要好一点。
准备切一个300正样本的。

2015年8月16日 18:29:21 更新
这次训练的是手动抠图50张bmp格式的图片做正样本,抠图比例尽量使用25:15的比例。负样本450张,训练9级,效果比较奇怪,无法解释,倒是检测速度很快


test2.jpg

而当训练到12级的时候效果就好了一点,但是其它的图片都圈不出来了。
test2.jpg

2015年8月16日 20:16:48 更新
本次使用156张手动抠图分辨率25:15的,负样本450张 训练到16级,有部分船只不能识别出来,但是不会把非船只的识别成船只,算是一种进步
test2.jpg
test2.jpg
test2.jpg
test2.jpg

2015年8月16日 21:38:35 更新
经过15次的各种训练尝试 证明手动抠图方法不适用
虽然说,用手动抠图的方式按照一定的比例抠图的方式效果要好一点,但是手动无法保证比例的准确性,其次手动抠图效率太低

那么我现在考虑的是一种等比例程序抠图,与前面用的等分辨率抠图比较会更少地掺入北京信息。

2015年8月17日 08:56:17 更新
现在最大的问题是抠图,有一个想法是确定一个常用的比例,等比例程序抠图,然后对抠得不好的图片手动抠图。
两种解决方案:
一是改写程序生成info.txt记录而不生成抠后的图片,要抠的每个图片中船只的坐标,对于抠的不好的,通过objectMarker程序来获取坐标,并修改info.txt里面的参数,这样做的好处是不用统一修改图片的分辨率,因为在训练的过程中会自动修改的。
二是不改写程序生成抠后的图片,并显示出常用的比例,然后对于不好的图片手动获取合适的坐标。然后手动裁剪。这样不好的地方是要使用统一的分辨率。

第五阶段

2015年8月17日 15:57:41 更新
个人觉得第一个方案比较好用,因为不必使用统一的分辨率只用使用同样的比例,这样就会减少一些图片中背景信息的内容。不过程序需要进行大量的修改。

所以这里用的抠图程序为了减少背景图片进行了两方面的优化:
1.与第一次使用的方法不同的是这里使用的是同比例而不是同分辨率,这样如果一个图片如果本来抠的图比较小,就不会因为要统一分辨率造成引入大量的背景信息。
2.手动法修正一些抠的不太好的图片。有成熟代码。

首先我们使用3:1的比例抠图,对于比例比这个小的增加宽度,对于比例比这个大的增加高度。如果增加宽度导致越界,可以只增加到边界处然后缩小高度,对于高度也是这样。

最后对于抠得不好的图片进行手动裁剪。
需要把边界保存在一个文件里面。保存圈出的图片。尽量简化程序。

下面使用120张正样本来程序等比例抠图+手动修正,然后训练分类器到16级的结果是,不会出现误检的情况(就是不是船检测成船),但是会出现漏检的情况,可能是正样本太少,也可能是使用的测试图像太奇怪的原因。总是效果是比较理想的,说明程序等比例抠图和手动修正的方法是比较正确的。同时速度也很快
但是需要手动修正的大概占1/4;

test2.jpg

test2.jpg

test2.jpg

test2.jpg

2015年8月18日 16:02:05 更新
已经得到比较好的正样本1088个。比例是30:10,训练到5级的时候效果奇差,速度5秒
训练到11级的时候效果较好,速度快 13级的时候效果更好。

test2.jpg

test2.jpg

test2.jpg

test2.jpg

test2.jpg

训练到15级的时候效果更好。
test2.jpg

test2.jpg

test2.jpg

训练到16级能识别奇葩的船只

004170.jpg 

007685.jpg

002605.jpg  

第六阶段

使用侧面和近侧面图像做正样本
使用pascal_voc2012中不含船只的图像做负样本;

1. 获取正样本,从前一阶段的正样本中选取然后修改描述文件

点击见用python生成正样本描述文件

2.获取负样本

用python提取不含船只的样本

第七阶段

阅读adaboost原理和cvHaarDetectObjects源码

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注