一个极其简单的图像识别小程序

前段时间写了个简单的图像识别程序,主要实现了对螺丝、螺母、硬币和小扳手的识别。现在来简单地做一个总结。
该程序的主要思路如下:

  1. 将采集到的RGB图像转化为灰度图像
  2. 应用OSTU算法对图像进行阈值分割并二值化
  3. 使用区域生长算法将各个待检测目标提取出来
  4. 根据目标的形状特征对目标进行分类

接下来对各个步骤做一些分析。

图像预处理

图像预处理是本实验的第一步。其目的是将目标物体的图像从背景中分割出来,这样我们才方便做后续的识别。
首先将RGB图像转换为灰度图像,是为了去除冗余的色彩信息,同时也简化了计算。
在灰度图像的基础上在进行图像分割。我们这里采取比较简单又较为常用的阈值分割法来进行图像分割。这里使用的OSTU算法是一种具有一定自适应性的阈值分割法,网络上有许多对这个算法的详细说明,我们这里不加赘述。

区域生长

虽然通过阈值分割我们已经得到了所有目标物体的像素分布,但是仅凭这个我们无法对每个物体的特征进行分析。因为我们并不知道单独的每个目标的像素分布。所以我们要寻找一种方法,将每个物体的像素信息分布保存起来。这种方法就是区域生长算法。区域生长的核心思想就是从种子点开始向相邻的点逐点搜索,从而将整个连通区域提取出来。
以下是该部分的源代码:

//返回生长区域点的个数
int CMainFrame::RegionGrow(Point init, vector<Point> &result, int **mark)
{
    stack<Point> seedStack;
    Point seed(0,0);
    int n = 0;  //区域内点的数量

    mark[init.y][init.x] = 1;
    seedStack.push(init);
    Point tmp(seed.x,seed.y);
    while (1)
    {
        seed = seedStack.top();
        seedStack.pop();
        if(seed.x < m_pBmpInfo->bmiHeader.biWidth-1)
        {
            tmp.x = seed.x + 1;
            tmp.y = seed.y;
            if(!mark[tmp.y][tmp.x] && gImageBuffer[tmp.y*m_pBmpInfo->bmiHeader.biWidth+tmp.x] == 0)
            {
                seedStack.push(tmp);
                result.push_back(tmp);
                mark[tmp.y][tmp.x] = 1;    //将已被生长的点标记为1
                n++;    //区域点的数量加一
            }
        }
        if(seed.y < m_pBmpInfo->bmiHeader.biHeight-1)
        {
            tmp.x = seed.x;
            tmp.y = seed.y + 1;
            if(!mark[tmp.y][tmp.x] && gImageBuffer[tmp.y*m_pBmpInfo->bmiHeader.biWidth+tmp.x] == 0)
            {
                seedStack.push(tmp);
                result.push_back(tmp);
                mark[tmp.y][tmp.x] = 1; 
                n++;
            }
        }
        if(seed.x > 0)
        {
            tmp.x = seed.x - 1;
            tmp.y = seed.y;
            if(!mark[tmp.y][tmp.x] && gImageBuffer[tmp.y*m_pBmpInfo->bmiHeader.biWidth+tmp.x] == 0)
            {
                seedStack.push(tmp);
                result.push_back(tmp);
                mark[tmp.y][tmp.x] = 1; 
                n++;
            }
        }
        if(seed.y > 0)
        {
            tmp.x = seed.x;
            tmp.y = seed.y - 1;
            if(!mark[tmp.y][tmp.x] && gImageBuffer[tmp.y*m_pBmpInfo->bmiHeader.biWidth+tmp.x] == 0)
            {
                seedStack.push(tmp);
                result.push_back(tmp);
                mark[tmp.y][tmp.x] = 1;  
                n++;
            }
        }

        if(seedStack.empty())
            break;
    }
    return n;
}

目标识别

在得到了各个目标的像素信息后,如何对目标进行分类呢?由于我们要识别的物体仅限于螺丝、螺母、硬币这样形状简单的物体,我们只需通过一些简单的特征就能将他们区分开来。

  • 螺母的中心为空,而螺丝、小扳手均为实心
  • 小扳手为L形的细杆,其长轴和短轴之比远大于螺丝
  • 硬币为圆形

凭借以上三条规则,就足以将螺丝、螺母、硬币和扳手区分开来了。

小结

本文主要是整理思路,细节的地方并未涉及,希望能对读者有一些帮助~
P.S. 此文在我新搭建的独立博客亦有发表:
http://cyanair.me/2016/03/31/a-simple-objection-recognition-program/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 不同图像灰度不同,边界处一般会有明显的边缘,利用此特征可以分割图像。需要说明的是:边缘和物体间的边界并不等同,边缘...
    大川无敌阅读 14,745评论 0 29
  • 1、阈值分割 1.1 简介 图像阈值化分割是一种传统的最常用的图像分割方法,因其实现简单、计算量小、性能较稳定而成...
    木夜溯阅读 22,911评论 9 15
  • 去年Alaph GO击败李世石九段,社会掀起了机器学习技术讨论的热潮,不过很多人对机器学习并不了解,本文借由手写数...
    Sunhaorong阅读 7,517评论 0 4
  • 图像识别意义: 图像是指物体的描述信息,数字图像是一个物体的数字表示。视觉是人类感知外部世界的最重要手段,据统计,...
    木木口丁阅读 12,783评论 1 21
  • 姓名:朱睿琦 学号:15180288015 【嵌牛导读】:随着数字图像处理技术和人工智能的不断发展,图像识别技术无...
    BLASSREITER阅读 9,477评论 0 0

友情链接更多精彩内容