文档章节

用递归方法实现图像的噪声

乱世中的单纯
 乱世中的单纯
发布于 2014/10/29 17:32
字数 1392
阅读 10
收藏 0

整个程序的流程是:

Main()

{

domain();    //寻找连通区域的总白点数

}

 

domain()

{

first()       //寻找连通区域的第一个白点数
{

round(){}    //寻找连通区域的其他白点数

}

}

 具体函数:

domain函数:声明两个数组num和flag。num用来存放对应像素点是黑点(0)或白点(1),flag用来标记对应像素点是否被访问过,未访问是false,访问过是true。考虑到检测连通区域时边缘可能会越界,因此将四周的flag设为true。

     first函数:用for循环寻找第一个白点,找到后将该白点的num值设为2(这是为后面判断连通区域白点个数作标记,如果连通区域白点个数小于阈值,就要把所有num为2的白点变成黑点)。然后调用round函数判断一片连通区域有多少个白点,如果多余阈值,就将num=2改为num=3(防止和下一个连通区域冲突),否则将所有num为2的白点变成黑点。

     round函数:将first函数找到的第一个白点的位置作为实参传过来。之后判断把连通区域的点是否为白点。同时对连通区域的白点又用递归调用round函数判断其连通区域,直到将一片连通区域的白点个数全部统计完。

 

代码中遇到的问题:

  1. clone函数已经包括将图片所有信息全部复制给另一个图片了,不用再单独将灰度值赋值了。如:

Mat img2=img1.clone();

//   img2.data[j*cols+i]=img1.data[j*cols+i]; 这一句不需要

  1. 尽量不使用全局变量,使用局部变量时,若其他函数不能用(变红),可以选择用传参的方式传给下一个函数。

  2. 对连通区域的第一个白点忘记标记为true,又忘记将第一个白点变黑。因此遇到了好多小白点没变黑的问题。

  3. 一个函数内不能定义另一个函数,但是可以调用。

  4. 结果效果不好可以调节灰度值的阈值和连通区域白点个数的阈值。

 

#include<opencv2/opencv.hpp>

#include<math.h>

using namespace cv;

using namespace std;

 

int rows,cols;

void domain(Mat img1) ;

void round(int xstart ,int ystart,int * num,bool * flag) ;

void first(int * num,bool * flag,Mat img2) ;

int number;

 

int main()

{

    Mat img= imread("1.jpg",CV_LOAD_IMAGE_GRAYSCALE );

    rows=img.rows;

    cols=img.cols;

   

    uchar *result;               //数组和地址的关系

    result=new uchar[rows*cols]; //动态分配一个数组result,存每个点的强度值,new分配的数组最后要用delete释放空间

 

    for(int j=0;j<(rows-1);j++)

    {

        for(int i=0;i<(cols-1);i++)

        {

        int x=img.data[j*cols+i]-img.data[(j+1)*cols+i+1];

        int y=img.data[(j+1)*cols+i]-img.data[j*cols+i+1];

        result[j*cols+i]=(uchar)sqrt(x*x+y*y);

 

        }

    }

    for(int j=0;j<(rows-1);j++)

    {

        for(int i=0;i<(cols-1);i++)

        {

            if(result[j*cols+i]<20)

            {

                img.data[j*cols+i] =0;

            }

            else

            {

                img.data[j*cols+i]=255;

            }

 

        }

        }

    delete [] result ;

   

   

    domain (img );

    namedWindow("image0", CV_WINDOW_AUTOSIZE);

    imshow("image0",img);

   

    waitKey();

    return 0;

}

   

void domain(Mat img1)   //找出一片区域的白点个数

{

    //int n;   //记录连通域白点个数

    Mat img2=img1.clone();

//  img2.data[j*cols+i]=img1.data[j*cols+i];

      int * num;  

    num=new int[rows*cols];

    bool * flag;

    flag=new bool[rows*cols];

 

    for(int j=0;j<rows;j++){

        for(int i=0;i<cols;i++){

            if(img2.data[j*cols+i]==255)

            {

                num[j*cols+i]=1;

                flag[j*cols+i]=false;

            }

            else

            {

                num[j*cols+i]=0;

                flag[j*cols+i]=false;

            }

        }

    }

    for(int i=0;i<cols;i++)       //四个边,第一行

        {

            flag[i]=true;

    }

    for(int i=0,j=rows-1;i<cols;i++)       //四个边,最后一行

        {

            flag[j*cols+i]=true;

    }

    for(int j=0;j<rows;j++)       //四个边,左边一列

        {

            flag[j]=true;

    }

    for(int i=cols-1,j=0;j<rows;j++)       //四个边,右边一列

        {

            flag[j*cols+i]=true;

    }

 

    first(num,flag,img2);

    namedWindow("image1", CV_WINDOW_AUTOSIZE);

    imshow("image1",img2);

    delete [] num ;

    delete [] flag ;

 

}

void first(int * num,bool * flag,Mat img2)   //寻找连通域的第一个白点

{

    for(int j=0;j<rows;j++){

        for(int i=0;i<cols;i++){

            if(num[j*cols+i]==1&&!flag[j*cols+i])

            {

                //round(i,j,num,flag);

                num[j*cols+i]=2;

                number=0;

                flag[j*cols+i]=true;

                round(i,j,num,flag);

                if(number<80)

                {

                  for(int a=0;a<rows;a++){

                  for(int b=0;b<cols;b++){

                  if(num[a*cols+b]==2)

                  {

                      img2.data[a*cols+b]=0;

                  }

                 

                  }

                  }

                }

                 else

                {

                    for(int a=0;a<rows;a++){

                  for(int b=0;b<cols;b++){

                  if(num[a*cols+b]==2)

                  {

                      num[a*cols+b]=3;

                  }

                 

                  }

                  }

                   

                }

            }

        }

    }

 

}

 

 

 

void round(int xstart ,int ystart,int * num,bool * flag)    //寻找连通域的白点数

{

   

    if(num[(ystart-1)*cols+xstart-1]==1&&!flag[(ystart-1)*cols+xstart-1])  //左上

    {

        number++;

        flag[(ystart-1)*cols+xstart-1]=true;

        num[(ystart-1)*cols+xstart-1]=2;

        round(xstart-1,ystart-1,num,flag);

    }

    if(num[(ystart-1)*cols+xstart]==1&&!flag[(ystart-1)*cols+xstart])  //

    {

        number++;

        flag[(ystart-1)*cols+xstart]=true;

        num[(ystart-1)*cols+xstart]=2;

        round(xstart,ystart-1,num,flag);

    }

    if(num[(ystart-1)*cols+xstart+1]==1&&!flag[(ystart-1)*cols+xstart+1])  //右上

    {

        number++;

        flag[(ystart-1)*cols+xstart+1]=true;

        num[(ystart-1)*cols+xstart+1]=2;

        round(xstart+1,ystart-1,num,flag);

    }

    if(num[ystart*cols+xstart-1]==1&&!flag[ystart*cols+xstart-1])  //

    {

        number++;

        flag[ystart*cols+xstart-1]=true;

        num[ystart*cols+xstart-1]=2;

        round(xstart-1,ystart,num,flag);

    }

    if(num[ystart*cols+xstart+1]==1&&!flag[ystart*cols+xstart+1])  //

    {

        number++;

        flag[ystart*cols+xstart+1]=true;

        num[ystart*cols+xstart+1]=2;

        round(xstart+1,ystart,num,flag);

    }

    if(num[(ystart+1)*cols+xstart-1]==1&&!flag[(ystart+1)*cols+xstart-1])  //左下

    {

        number++;

        flag[(ystart+1)*cols+xstart-1]=true;

        num[(ystart+1)*cols+xstart-1]=2;

        round(xstart-1,ystart+1,num,flag);

    }

    if(num[(ystart+1)*cols+xstart]==1&&!flag[(ystart+1)*cols+xstart])  //

    {

        number++;

        flag[(ystart+1)*cols+xstart]=true;

        num[(ystart+1)*cols+xstart]=2;

        round(xstart,ystart+1,num,flag);

    }

    if(num[(ystart+1)*cols+xstart+1]==1&&!flag[(ystart+1)*cols+xstart+1])  //右下

    {

        number++;

        flag[(ystart+1)*cols+xstart+1]=true;

        num[(ystart+1)*cols+xstart+1]=2;

        round(xstart+1,ystart+1,num,flag);

    }

   

}

 

© 著作权归作者所有

乱世中的单纯
粉丝 12
博文 65
码字总数 36866
作品 0
广州
程序员
私信 提问
吴恩达斯坦福CS230第一名:图像超级补全,效果惊艳(附代码)

【新智元导读】图像修复(Image inpainting)是一个已经被广泛研究的计算机视觉问题,即恢复图像中缺失的部分。斯坦福大学CS230课程的Mark Sabini等人提出“Image outpainting”,比图像修复...

技术小能手
2018/07/31
0
0
这些深度学习术语,你了解多少?(下)

这些深度学习术语,你了解多少?(上) 动量(Momentum) Momentum是Gradient Descent算法的扩展、可加速或抑制参数更新。 1、通过反向传播的错误来学习表征 多层感知器(MLP) 多层感知器是...

【方向】
2018/10/26
0
0
【工具使用系列】关于 MATLAB 图像复原 & 图像重建,你需要知道的事

如何进行图像复原 & 图像重建 添加噪声 用imnoise函数为图像添加噪声 用给定分布产生空间随机噪声 周期噪声 估计噪声参数 消除噪声 仅有噪声的复原 空间噪声滤波器 自适应空间滤波器 周期噪声...

AllenMoore
2018/01/27
5
0
【图像处理】空间滤波、中值滤波(Spatial Filtering and Median Filtering)

实验要求   编写一个能够完成两幅图像之间加、减、乘、除四种算术运算的函数。另外,对于两幅图像的乘法,所编写的乘法程序还要能够完成一幅图像乘以一个常数的功能。使用图Fig1.10(4)和F...

u013165921
2018/01/15
0
0
基于MATLAB的均值滤波算法实现

  在图像采集和生成中会不可避免的引入噪声,图像噪声是指存在于图像数据中的不必要的或多余的干扰信息,这对我们对图像信息的提取造成干扰,所以要进行去噪声处理,常见的去除噪声的方法有...

NingHeChuan
2018/08/23
0
0

没有更多内容

加载失败,请刷新页面

加载更多

跨域的理解,以及解决方案!

/*什么是跨域? * 跨域的主要原因是浏览器的同源策略。 * =>>所谓的同源策略就是A网页设置的 Cookie,B网页不能打开,除非这两个网页"同源"。 * 什么是同源? * =>>同源就是协议相同、域名相同...

流年那么伤
34分钟前
4
0
Nginx配置try_files,php无法获取$_GET参数

平时开发都是用LNMP,新安装的虚拟机在配置nginx的rewrite的时候使用try_files命令。但是在写的时候配置成“try_files $uri $uri/ /index.php?q=args;”, 在PHP的web程序中,打印$_GET为空。...

叫我哀木涕
35分钟前
3
0
【原创】Microsoft Edge可以用localhost访问但无法用IP访问

Microsoft Edge可以用localhost和127.0.0.1访问但无法用本机IP访问, chrome ie都可以推测是edge的问题,网络是专用网络,防火墙也关了: 在edge里 按F12 以在控制台里看到这句 CONSOLE21301...

shzwork
35分钟前
1
0
Python利用数学方程式画4种不一样的心型图案

前言 下面这四个心型图案,是通过科学地计算,根据数学方程式生成的,虽然做的不是特别完美,但是基本的还是能实现的 第一个心型 结果图 第二心型 结果图 学习从来不是一个人的事情,要有个相互监...

A_裙232550246
36分钟前
2
0
微信带场景参数的二维码生成与使用?

微信公众号推广时,用户通过扫二维码关注公众号,需要统计用户是通过谁的二维码进行关注。 在用户扫码关注公众号时,二维码带上推广者的参数,在关注公众号后,获取到该推广者的参数。 目前有...

wxgzhgncj
36分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部