提取图像里面的红色灯笼(一)

图像的分割:RGB空间图像的分割:

/**************************************************************
函数功能:对图像rgb空间红色灯笼的提取
输入参数:源图像src;目标图像des;图像参数width,height,nChannels;
输出参数:目标图像
**************************************************************/
void rgb_seg(unsigned char* des, const unsigned char* src, int width, int height, int nChannels)
{
         printf("%d,%d,%d,",nChannels,width,height);
         unsigned char* ocl = new unsigned char[width * height * nChannels];
         for(int y = 0; y < height; y++)
             {
                       for(int x = 0; x < width; x++)
                       {
                            int img_B= src[y * width * nChannels + x * nChannels ] ;
                            int img_G= src[y * width * nChannels + x * nChannels + 1] ;
                            int img_R= src[y * width * nChannels + x * nChannels + 2] ;
                                if((img_R>140)&&(img_G<70)&&(img_B<70))                 //简单的阈值提取
                                         for(int n=0;n<nChannels;n++)
                                    des[y * width * nChannels + x * nChannels + n] = src[y * width * nChannels + x * nChannels + n] ;
                                else
                                        for(int n=0;n<nChannels;n++)
                                        des[y * width * nChannels + x * nChannels + n] =255;
                       }
             }
             ImageDilation(ocl, des,  width, height, nChannels,7);//用7*7的模板进行膨胀
             ImageErosion(des, ocl, width, height, nChannels,13); //用13*13的模板进行腐蚀
             ImageDilation(ocl, des, width, height, nChannels,13);//用13*13的模板进行膨胀
             ImageReturn(des,ocl,src, width, height, nChannels,10);//用10*10的模板还原灯笼
}

  

下图第一幅为简单的红色分量阈值分割,第二幅为对前一副图像7*7的模板的膨胀。

下图第一幅为用13*13的模板进行腐蚀,第二幅用13*13的模板再次进行膨胀:

可见再次膨胀后的图像消除了所有的噪点,我们对这幅图像进行还原,还原的基本原理就是对图像有红色区域的部分用源图像进行相对应位置的填充。如下所示,对比原图可见其较好的找出了灯笼的轮廓。

 

图像的分割:HSI空间图像的分割:

/**************************************************************
函数功能:对图像hsi空间红色灯笼的提取
输入参数:源图像src;目标图像des;图像参数width,height,nChannels;
输出参数:目标图像
**************************************************************/
void hsi_seg(unsigned char* des, const unsigned char* src, int width, int height, int nChannels)
{
         printf("%d,%d,%d,",nChannels,width,height);
         unsigned char* ocl = new unsigned char[width * height * nChannels];
         unsigned char* hsi = new unsigned char[width * height * nChannels];
         rgb_hsi(hsi,src, width,  height,  nChannels);    //hsi分量提取
         for(int y = 0; y < height; y++)
             {
                       for(int x = 0; x < width; x++)
                       {
                            int img_H= hsi[y * width * nChannels + x * nChannels ] ;
                            int img_S= hsi[y * width * nChannels + x * nChannels + 1] ;
                            int img_I= hsi[y * width * nChannels + x * nChannels + 2] ;
                                if(((img_H<104)&&(img_H>102))&&(img_I>40)&&(img_S>160))
                                     {
                                               //printf("%d, ",img_S);
                                         for(int n=0;n<nChannels;n++)
                                    des[y * width * nChannels + x * nChannels + n] = src[y * width * nChannels + x * nChannels + n] ;
                                     }
                                else
                                        for(int n=0;n<nChannels;n++)
                                        des[y * width * nChannels + x * nChannels + n] =255;

                       }
             }
             ImageErosion(ocl, des, width, height, nChannels,2);       //进行2*2的模板腐蚀
                   ImageDilation(des, ocl,  width, height, nChannels,18);//进行18*18的模板膨胀
                   memcpy(ocl, des, nChannels*width*height);
             ImageReturn(des,ocl,src, width, height, nChannels,10);//进行10*10的模板还原
}

  

下图第一幅图像为HIS空间对图像进行的简单的阈值分割,分割条件:

((img_H<104)&&(img_H>102))&&(img_I>40)&&(img_S>160)

可见其噪点很少,对其进行2*2的模板腐蚀再进行18*18的模板膨胀,如下右图所示:

可见右图已经比较好的找出了灯笼的位置,我们用进行10*10的模板还原得到下面的图,和原图比较,也得到了比较好的效果。

下面是图像腐蚀、膨胀、还原的代码:

/**************************************************************
函数功能:对图像进行M*M模板的腐蚀
输入参数:源图像src;目标图像des;图像参数width,height,nChannels;腐蚀边长M
输出参数:目标图像
**************************************************************/
void ImageErosion(unsigned char* des, const unsigned char* src, int width, int height, int nChannels,int M)
{
         memcpy(des, src, nChannels*width*height);
         int m,p,k=0,q=0;
         for(int y = 20; y < height-20; y++)
             {
                       for(int x = 20; x < width-20; x++)
                {
                    if((src[y * width * nChannels + x * nChannels + 2]!=255))
                    {
                                                        k=k+1;
                                                        for(m=-M;m<=M;m++)
                        {
                        for(p=-M;p<=M;p++)
                            {
                                                                 if((src[(y+m) * width * nChannels + (x+p) * nChannels + 2])==255)
                                                                 {
                                                                   for(int n=0;n<nChannels;n++)
                              des[y * width * nChannels + x * nChannels + n]=255;
                                                                 }
                             }
                        }
                                               }
                                               else
                                               {
                                                        q=q+1;
                                               }
             }
       }
         //printf("E%d   %d",k,q);
}

/**************************************************************
函数功能:对图像进行M*M模板的膨胀
输入参数:源图像src;目标图像des;图像参数width,height,nChannels;膨胀边长M
输出参数:目标图像
**************************************************************/
void ImageDilation(unsigned char* des, const unsigned char* src, int width, int height,int nChannels,int M)
{
             int m,p,k=0,q=0;
                   memcpy(des, src, nChannels*width*height);
         for(int y = 20; y < height-20; y++)
             {
                       for(int x = 20; x < width-20; x++)
                {
                    if((src[y * width * nChannels + x * nChannels + 2]!=255))
                    {
                                                        k=k+1;
                                                        for(m=-M;m<=M;m++)
                        {
                        for(p=-M;p<=M;p++)
                            {
                                                                   for(int n=0;n<nChannels;n++)
                              des[(y+m) * width * nChannels + (x+p) * nChannels + n]=src[y * width * nChannels + x * nChannels + n];
                             }
                        }
                                               }
                                               else
                                               {
                                                        q=q+1;
                                               }
             }
       }
         //printf("D%d  %d",k,q);
}
/**************************************************************
函数功能:对图像进行M*M模板的原图像还原
输入参数:源图像src;目标图像des;图像参数width,height,nChannels;还原边长M
输出参数:目标图像
**************************************************************/
void ImageReturn(unsigned char* des, const unsigned char* ocl, const unsigned char* src, int width, int height, int nChannels,int M)
{
         memcpy(des, ocl, nChannels*width*height);
         int m,p,k=0,q=0;
         for(int y = 30; y < height-30; y++)
             {
                       for(int x = 30; x < width-30; x++)
                {
                    if((ocl[y * width * nChannels + x * nChannels + 2]!=255))
                    {
                                                        k=k+1;
                                                        for(m=-M;m<=M;m++)
                        {
                        for(p=-M;p<=M;p++)
                            {
                                                                 int B= src[(y+m) * width * nChannels + (x+p) * nChannels ] ;
                                            int G= src[(y+m) * width * nChannels + (x+p) * nChannels + 1] ;
                                            int R= src[(y+m) * width * nChannels + (x+p) * nChannels + 2] ;
                                             if(R>130)
                                                                  {
                                                                   for(int n=0;n<nChannels;n++)
                              des[(y+m) * width * nChannels + (x+p) * nChannels + n]=src[(y+m) * width * nChannels + (x+p) * nChannels + n];
                                                                  //将还原区域用源图像进行填充
                                                                  }
                             }
                        }
                                               }
             }
       }
}

  

时间: 2024-08-06 03:44:43

提取图像里面的红色灯笼(一)的相关文章

提取图像里面的红色灯笼(二)

首先对图像进行简单的阈值处理: /************************************************************** 函数功能:对图像hsi空间红色灯笼的提取 输入参数:源图像src:目标图像des:图像参数width,height,nChannels: 输出参数:目标图像 **************************************************************/ void hsi_seg(unsigned char*

OpenCV提取图像轮廓总结

OpenCV函数 cvFindContours提取轮廓 :点击打开链接  点击打开链接 点击打开链接 点击打开链接 提取元素的轮廓及形状描述子 点击打开链接 提取轮廓的点坐标 轮廓提取后,它是用关键点组成的,下面提取出这些关键点. 1.先输出所有关键点的个数cout<<"elements"<<contour->total<<endl; 2.for(int i=0;i<contour->total;++i) { CvPoint* p

条形码读取控件Softek Barcode Reader Toolkit提取图像中条形码信息

Softek Barcode Reader Toolkit是一款功能强大的条形码读取控件,提取图像中条形码信息的综合工具包.可用在扫描.索引文件的应用程序中.条形码信息可高速准确地从文件中读取,无需介入操作,应用程序就可索引图像. 具体功能: 支持一维和二维条形码 shell(命令解析器)工具. C语言的API(应用程序接口). Perl(实用报表提取语言)模式. Java(TM)类. 图像消噪. 兼容常规的表达形式. 通过条形码的位置可分离多页的TIF文件. 支持彩色图像, 创建Code 39

原来CNN是这样提取图像特征的。。。

对于即将到来的人工智能时代,作为一个有理想有追求的程序员,不懂深度学习(Deep Learning)这个超热的领域,会不会感觉马上就out了?作为机器学习的一个分支,深度学习同样需要计算机获得强大的学习能力,那么问题来了,我们究竟要计算机学习什么东西?答案当然是图像特征了.将一张图像看做是一个个像素值组成的矩阵,那么对图像的分析就是对矩阵的数字进行分析,而图像的特征,就隐藏在这些数字规律中.深度学习对外推荐自己的一个很重要的点--深度学习能够自动提取特征.本文主要介绍卷积层提取特征的原理过程,文

matlab 提取图像轮廓(图像边缘提取)

利用edge()函数提取图像轮廓,绘制出对象的边界和提取边界坐标信息,matlab实现代码如下: close all;clear all;clc; % 提取图像轮廓,提取图像边缘 I = imread('yifu.jpg'); c = im2bw(I,graythresh(I)); figure; subplot(131);imshow(I); c = flipud(c); %实现矩阵c上下翻转 b = edge(c,'canny'); [u,v] = find(b); %返回边界矩阵b中非零元

CNN基础二:使用预训练网络提取图像特征

上一节中,我们采用了一个自定义的网络结构,从头开始训练猫狗大战分类器,最终在使用图像增强的方式下得到了82%的验证准确率.但是,想要将深度学习应用于小型图像数据集,通常不会贸然采用复杂网络并且从头开始训练(training from scratch),因为训练代价高,且很难避免过拟合问题.相对的,通常会采用一种更高效的方法--使用预训练网络. 预训练网络的使用通常有两种方式,一种是利用预训练网络简单提取图像的特征,之后可能会利用这些特征进行其他操作(比如和文本信息结合以用于image capti

利用OpenCV检测图像中的长方形画布或纸张并提取图像内容

基于知乎上的一个答案.问题如下: 也就是在一张照片里,已知有个长方形的物体,但是经过了透视投影,已经不再是规则的长方形,那么如何提取这个图形里的内容呢?这是个很常见的场景,比如在博物馆里看到一幅很喜欢的画,用手机找了下来,可是回家一看歪歪斜斜,脑补原画内容又觉得不对,那么就需要算法辅助来从原图里提取原来的内容了.不妨把应用的场景分为以下: 纸张四角的坐标(图中红点)已知的情况 也就是上面的左图中4个红点是可以准确获取,比如手动标注,那么就简单了:用OpenCV的Perspective Trans

python-opencv在有噪音的情况下提取图像的轮廓

对于一般的图像提取轮廓,这篇博文介绍了一个很好的方法,但是对于有噪声的图像,并不能很好地捕获到目标物体. 比如对于我的鼠标,提取的轮廓效果并不好,因为噪声很多: 所以本文增加了去掉噪声的部分. 首先加载原始图像,并显示图像 1 img = cv2.imread("temp.jpg") #载入图像 2 h, w = img.shape[:2] #获取图像的高和宽 3 cv2.imshow("Origin", img) #显示原始图像 然后进行低通滤波处理,进行降噪 1

提取图像边缘

利用java打开一张图片,并提取其边缘.功能有打开文件,以及提取边缘. 算法原理 由于边缘提取的算法有很多种,而提取的精度在相同阈值的情况下也会有不同的结果. 这次我的边缘提取使用索贝尔算子(Sobel operator). 该算子会把图像每一点的灰度矢量计算出来.而分别为横向及纵向,将之与图像作平面卷积,即可分别得出横向及纵向的亮度差分近似值. 算法核心: public int getGrayPoint(int x, int y) { return grayData[y * width + x