整个工程进展到这一步也算是不容易吧,但技术含量也不怎么高,中间乱起八糟的错误太烦人了,不管怎么样,现在面临了最大的困难吧,图像处理算法。算法确实不好弄啊,虽然以前整过,但都不是针对图像的。

现在的图像算法太多了,好像谁都在研究,没有一个统一的路线,看论文也是越看越糊涂,无奈之下还是自己好好学学吧,幸好队友以前也搞过,大家也都愿意参与进来了,很开心!

首先改变下策略吧,之前一直在linux中直接在QT中利用OpenCV库进行图像处理的尝试,但是效率太差了,每次想要结果,都要用板子,所以,现在改用OpenCV+vs2010现在PC上测试,直到满意了再复制到板子上进行测试。

换工具,得先配置啊,还好之前搞过,使用的人也多,所以比较顺利:参考博客

http://www.cnblogs.com/jamiechu/archive/2012/03/01/2376266.html

自己写程序,测试结果编译出错:LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏

百度了,http://www.cppleyuan.com/forum.php?mod=viewthread&tid=10226这个帖子不错,安装完补丁之后,编译生成解决方案成功。

测试了小程序,可以使用了。

针对自己的问题吧,现在的问题是月牙提取不出来,所以绞尽脑汁、千方百计要把这月牙给分离出来,找方法一个一个试吧。

话说加入OpenCV后编译又出现一个错误:

http://xuzhihong1987.blog.163.com/blog/static/2673158720122315223150/这个方法解决了。

首先我们已经对图像进行了初步的分割,可以将指甲的轮廓提取出来,只是效果不是很理想。可以看到受光照影响明显,需要采取措施解决光照问题。如下图:

现在想要通过对扣取出来的图片进行进一步处理,也就是对第二幅图进行特征提取,从中找到我们所需的月牙,月牙和甲床面积比,月牙颜色,甲床颜色,甲床上是否有斑点、横纹、纵纹,从而为后面的医学诊断理论作依据。

既然基于灰度图像已经不能再有任何进展了,不如就用彩色图像分割吧。之前也探索过,发现还是有一定的效果的。

RGB颜色空间是图像处理中最基本、最常用、面向硬件的颜色空间。我们采集到的彩色图像,一般就是被分成R、G、B的成分加以保存的。然而,自然环境下获取的果实图像容易受自然光照、叶片遮挡和阴影等情况的影响,即对亮度比较敏感。而RGB颜色空间的分量与亮度密切相关,即只要亮度改变,3个分量都会随之相应地改变。所以,RGB颜色空间适合于显示系统,却并不适合于图像处理。

HSLHSV(也叫HSB)是对RGB 色彩空间中点的两种有关系的表示,它们尝试描述比 RGB 更准确的感知颜色联系,并仍保持在计算上简单。

H指hue(色相)、S指saturation(饱和度)、L指lightness(亮度)、V指value(色调)、B指brightness(明度)。

  • 色相(H)是色彩的基本属性,就是平常所说的颜色名称,如红色黄色等。
  • 饱和度(S)是指色彩的纯度,越高色彩越纯,低则逐渐变灰,取0-100%的数值。
  • 明度(V),亮度(L),取0-100%。

根据这幅图就能很好地理解HSV空间了。所以接下来就采用彩色图像进行分析看看效果。

,貌似可以先将指甲抠出来。不管怎样,先试试。

首先查论文,看到的好多是聚类方法,kmeans方法首先来,幸好OpenCV也有这函数,先来学学。

K-means算法是最为经典的基于划分的聚类方法,是十大经典数据挖掘算法之一。K-means算法的基本思想是:以空间中k个点为中心进行聚类,对最靠近他们的对象归类。通过迭代的方法,逐次更新各聚类中心的值,直至得到最好的聚类结果。

我的OpenCV的版本是2.3.1. 其中Kmean的实现在modulescoresrcmatrix.cpp里面,这里要推荐一个博客,讲得挺清楚:http://www.hongquan.me/?p=8

例子可以看:http://blog.csdn.net/xwu6614555/article/details/8568030

double cv::kmeans( InputArray _data, int K,  InputOutputArray _bestLabels, TermCriteria criteria, int attempts, int flags, OutputArray _centers )

下面就是分析这个函数了。

_data: 这个就是你要处理的数据,例如是一个CvMat数据

K : 你需要最终生成的cluster的数量

_bestLabels: 当cv::kmeans执行完毕以后, _bestLabels里面储存的就是每一个对应的数据元素所在的cluster的index,这样你就可以更新你的数据,就是标记矩阵。

criteria: 这个东西是用来告诉cv::kmeans以一个什么样的停止条件来运行,例如criteria.epsilon = 0.01f;criteria.type = CV_TERMCRIT_EPS; 这个表示centers在两轮cluster运行以后的距离差,如果这个距离小于等于criteria.epsilon就停止返回当前得到的centers,否则继续

attempts: 最多尝试多少次,文档上说一般设置为2

flags: 这个主要是传递一些配置参数,例如 初始的时候使用user code给定的label –KMEANS_USE_INITIAL_LABELS,若使用kmeans++初始化算法– KMEANS_PP_CENTERS

_centers: 这个就是我们想要的结果了,该函数运行完毕以后,这个变量里面储存所有的center的数据,也就是你想要的东西了,引用例子的程序,稍作修改就拿来用了。

void kmeans_mat(const Mat& src_img,Mat& dst_img)
{
int width_src=src_img.cols;
int height_src=src_img.rows; Mat samples=Mat::zeros(width_src*height_src,,CV_32FC3);//创建样本矩阵,CV_32FC3代表32位浮点3通道(彩色图像)
Mat clusters;//类别标记矩阵
int k=;
for (int i=;i<height_src;i++)
{
for (int j=;j<width_src;j++,k++)
{
//将像素点三通道的值按顺序排入样本矩阵
samples.at<Vec3f>(k,)[]=(float)src_img.at<Vec3b>(i,j)[];
samples.at<Vec3f>(k,)[]=(float)src_img.at<Vec3b>(i,j)[];
samples.at<Vec3f>(k,)[]=(float)src_img.at<Vec3b>(i,j)[];
}
}
int nCuster=;//聚类类别数,自己修改。
//聚类,KMEANS PP CENTERS Use kmeans++ center initialization by Arthur and Vassilvitskii
kmeans(samples,nCuster,clusters,TermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,,1.0),,KMEANS_PP_CENTERS); //显示聚类结果
if (dst_img.empty())
{
dst_img=Mat::zeros(height_src,width_src,CV_8UC1);
} k=;
int val=;
float step=/(nCuster-);
for (int i=;i<height_src;i++)
{
for (int j=;j<width_src;j++,k++)
{
val=-clusters.at<int>(k,)*step;//int
dst_img.at<uchar>(i,j)=val;
}
}
}

来看看聚类结果先:

聚类效果还不错,只是比原本的指甲小了点,需要进一步修改,或者和前面的边缘提取相结合进行修正。而且聚类的数目需要人来控制。

我在opencv的处理中总是遇到一个问题:Bad argument (Ukown array type) in cvarrToMat,后来发现是opencv库函数的使用问题,他有c的也有c++的,Mat一般是c++下的,所以用c的库函数会出现这个问题。

另外c版本中的保存图片为cvSaveImage()函数,c++版本中直接与matlab的相似,imwrite()函数。小插曲!

Zedboard甲诊opencv图像处理(三)的更多相关文章

  1. Zedboard甲诊opencv图像处理(四)

    接着上一篇博客,继续改进,现在为了是图像处理结果更加稳定,我实在没有办法了,只好先提取手指,再提取指甲. 把手指从背景里面提出来还是挺简单的,可惜的是我研究这么半天还是这结果,好沮丧. 怎么办呢,时间 ...

  2. Zedboard甲诊opencv图像处理(二)

    通过前面的努力已经得到了n个轮廓了,现在要把最终的轮廓确定下来 ,然后进行特征提取. 先深入分析下轮廓和处理轮廓的方法:http://blog.csdn.net/hitwengqi/article/d ...

  3. OpenCV图像处理篇之边缘检测算子

    OpenCV图像处理篇之边缘检测算子 转载: http://xiahouzuoxin.github.io/notes/ 3种边缘检测算子 一阶导数的梯度算子 高斯拉普拉斯算子 Canny算子 Open ...

  4. Python+OpenCV图像处理(一)

    Python+OpenCV图像处理(一): 读取,写入和展示图片 调用摄像头拍照 调用摄像头录制视频 1. 读取.写入和展示图片 图像读入:cv2.imread() 使用函数cv2.imread() ...

  5. 1.5快速上手OpenCV图像处理

    在上一节中,已经完成了OPENCV的配置,在本节接触几个Opencv图像处理相关的程序,看看opencv用简洁的代码能够实现哪些有趣的图像效果. 1.第一个程序:图像显示 #include<op ...

  6. opencv第三课,图像滤波

    1.介绍 OpenCV图像处理技术中比较热门的图像滤波操作主要被分为了两大类:线性邻域滤波和非线性滤波.线性邻域滤波常见的有“方框滤波“,”均值滤波“和”高斯滤波“三种,二常见的非线性滤波主要是中值滤 ...

  7. 《OpenCV图像处理编程实例》

    <OpenCV图像处理编程实例>例程复现 随书代码下载:http://www.broadview.com.cn/28573 总结+遇到的issue解决: 第一章 初识OpenCV 1.VS ...

  8. OpenCV图像处理学习笔记-Day1

    OpenCV图像处理学习笔记-Day1 目录 OpenCV图像处理学习笔记-Day1 第1课:图像读入.显示和保存 1. 读入图像 2. 显示图像 3. 保存图像 第2课:图像处理入门基础 1. 基本 ...

  9. zedboard上移植OPENCV库

    zedboard上移植OPENCV库 之前做了很多移植OPENCV库的工作,但是需要包含的各种库,需要交叉编译,X264 ,JPGE ,FFMPGE等等 注意:在<嵌入式系统软硬件协同设计实战指 ...

随机推荐

  1. 怎么样学好C++

    声明:这篇文章非本人所写,转自:http://coolshell.cn/articles/4119.html 昨天写了一篇如何学好C语言,就有人回复问我如何学好C++,所以,我把我个人的一些学习经验写 ...

  2. R语言——包的添加和使用

    R是开源的软件工具,很多R语言用户和爱好者都会扩展R的功能模块,我们把这些模块称为包.我们可以通过下载安装这些已经写好的包来完成我们需要的任务工作. 包下载地址:https://cran.r-proj ...

  3. nginx反向代理nginx,RealServer日志打印真实ip

    title: nginx反向代理nginx,RealServer日志打印真实ip date: 2016-05-11 19:15:37 tags: --- nginx反向代理nginx,RealServ ...

  4. ASP.NET MVC上传文件的几种方法

    1.Form表单提交 <p>Form提交</p> <form action="@Url.Action("SavePictureByForm" ...

  5. 基本 XAML 语法指南

    我们介绍了 XAML 语法规则,以及用于描述 XAML 语法中存在的限制或选项的术语.当出现以下情况时你会发现本主题很有用:不熟悉 XAML 语言的使用,希望加强对术语或某些语法部分的理解,或者对 X ...

  6. 重新认识Intent

    相信android开发工程师,对Intent一定不陌生,在整个开发中随时都用到了,今天我们总结一下Intent. 1. 为什么需要Intent? 在android Intent机制是协助应用间的交互与 ...

  7. oracle数据库exp/imp命令详解

    转自http://wenku.baidu.com/link?url=uD_egkkh7JtUYJaRV8YM6K8CLBT6gPJS4UlSy5WKhz46D9bnychTPdgJGd7y6UxYtB ...

  8. Swift - IBOutlet返回nil(fatal error: unexpectedly found nil while unwrapping an Optional value)

    在Swift 中 ViewController 默认构造方法不关联同名的xib文件 在使用OC的时候,调用ViewController的默认构造函数,会自动关联到一个与ViewController名字 ...

  9. 3月25日 javascript练习

    1.找出100以内带7的数字 2.求1!+2!+3!+......+n!的和

  10. Sql数据保存到Excel文件中

    public string ExportExcel( DataSet ds,string saveFileName) { try { if (ds == null) return "数据库为 ...