转载至http://blog.csdn.net/hujingshuang/article/details/44257179

前言:图像修复是一项非常有意义的研究工作,比如我们生活中的照片被污染,再比如名贵字画、国家文物壁画等珍贵物品被破坏,这些都需要图像修复工作来完成。

简介:整体变分(Total Variation)的方法最早是用来对受到噪声污染的图像进行降噪的,在这方面的应用最早是由L.Rudin和S.Osher等人在1992年提出的,2002年Chan等人把TV模型推广到图像修补中,并提出了基于TV模型的图像修补方法,同时说明了TV修补模型的缺点,进一步提出了CDD修补模型(curvature driven diffusions),此修补模型改正了TV修补模型的缺陷,对图像的修补具有很好的效果。

一、TV模型介绍

如图所示:D区域是被污染区(待修复),E是D的邻域

下面直接给出TV模型的数学公式:

                      ①

其中:u是图像中的像素点,λ为设定的参数

在该模型基础上,考虑到噪声的影响,边界E区域产生的噪声不能超过一定的范围;根据最佳猜测和贝叶斯理论,要求图像u在满足约束条件下使它的能量泛函最小,因此约束条件记做:公式②。根据拉格朗日乘数法,将①②方程转化成为一个求极值的方程,对其求导数并令其等于0,可得到如下方程:

其中:div代表散度(关于图像中的散度解释,可见此处:在图像处理中,散度 div 具体的作用是什么?)

由于图像是离散的数值,故可看做如下构成。其中:O为污染点,邻域B=(N,S,W,E),半像素邻域B' =(n,s,w,e)。

因此,离散化后可得到表达式:

化简得到最终的表达式:

其中:λe(O)为中心O处的λ参数,与上λe一致;uo为O点修复后的像素,另一个为O点修复前的原始像素。将上式迭代,知道达到较好的修复效果。

到此,TV模型的理论推导已完成。接下来就是要编程实现其功能。

matlab源码实现:

  1.  1 img=double(imread('lena.jpg'));
     2 mask=imread('mask.jpg');
     3 a1=find(mask>127);
     4 b1=find(mask<=127);
     5 mask(a1)=0;
     6 mask(b1)=255;
     7 [m n]=size(img);
     8 for i=1:m
     9     for j=1:n
    10         if mask(i,j)==0
    11            img(i,j)=0;
    12         end
    13     end
    14 end
    15 imshow(img,[]);     %合成的需要修复的图像
    16
    17 lambda=0.2;
    18 a=0.5;%避免分母为0
    19 imgn=img;
    20 for l=1:1500         %迭代次数
    21     for i=2:m-1
    22         for j=2:n-1
    23             if mask(i,j)==0     %如果当前像素是被污染的像素,则进行处理
    24                 Un=sqrt((img(i,j)-img(i-1,j))^2+((img(i-1,j-1)-img(i-1,j+1))/2)^2);
    25                 Ue=sqrt((img(i,j)-img(i,j+1))^2+((img(i-1,j+1)-img(i+1,j+1))/2)^2);
    26                 Uw=sqrt((img(i,j)-img(i,j-1))^2+((img(i-1,j-1)-img(i+1,j-1))/2)^2);
    27                 Us=sqrt((img(i,j)-img(i+1,j))^2+((img(i+1,j-1)-img(i+1,j+1))/2)^2);
    28
    29                 Wn=1/sqrt(Un^2+a^2);
    30                 We=1/sqrt(Ue^2+a^2);
    31                 Ww=1/sqrt(Uw^2+a^2);
    32                 Ws=1/sqrt(Us^2+a^2);
    33
    34                 Hon=Wn/((Wn+We+Ww+Ws)+lambda);
    35                 Hoe=We/((Wn+We+Ww+Ws)+lambda);
    36                 How=Ww/((Wn+We+Ww+Ws)+lambda);
    37                 Hos=Ws/((Wn+We+Ww+Ws)+lambda);
    38
    39                 Hoo=lambda/((Wn+We+Ww+Ws)+lambda);
    40                 value = Hon*img(i-1,j)+Hoe*img(i,j+1)+How*img(i,j-1)+Hos*img(i+1,j)+Hoo*img(i,j);
    41                 imgn(i,j)= value;
    42             end
    43         end
    44     end
    45     img=imgn;
    46 end
    47 figure;
    48 imshow(img)

    opencv源码实现:


  2.  1 #include <iostream>
     2 #include <stdlib.h>
     3 #include <cv.h>
     4 #include <math.h>
     5 #include <opencv2/highgui/highgui.hpp>
     6 #include <opencv2/core/core.hpp>
     7 #include <opencv2/imgproc/imgproc.hpp>
     8
     9 using namespace cv;
    10
    11 int main(void)
    12 {
    13     //读取原始图像及掩模图像
    14     IplImage *src_uint8 = cvLoadImage("src.jpg", CV_LOAD_IMAGE_GRAYSCALE);
    15     IplImage *mask = cvLoadImage("mask.jpg", CV_LOAD_IMAGE_GRAYSCALE);
    16     //合成需要修复的图像
    17     int M = mask->height;
    18     int N = mask->width;
    19     int i, j;
    20     CvMat *src = cvCreateMat(M, N, CV_32FC1);//存放浮点图像
    21     cvConvert(src_uint8, src);
    22     for (i = 0; i < M; i++)
    23     {
    24         for (j = 0; j < N; j++)
    25         {
    26             if ((mask->imageData + i * mask->widthStep)[j] < 0)//理解此处判别条件,根据情况自行更改
    27             {
    28                 ((float*)(void*)(src->data.ptr + (size_t)src->step*i))[j] = 0.0;
    29             }
    30             if (((float*)(void*)(src->data.ptr + (size_t)src->step*i))[j] < 0)
    31             {
    32                 ((float*)(void*)(src->data.ptr + (size_t)src->step*i))[j] += 256.0;
    33             }
    34         }
    35     }
    36     cvConvert(src, src_uint8);
    37     cvShowImage("需要修复的图像", src_uint8);
    38     cvWaitKey(0);
    39
    40     double t = getTickCount();//当前滴答数
    41     float lambda = 0.2;
    42     float delta = 0.5;
    43     float UO, UN, UW, US, UE, UNE, UNW, USW, USE;
    44     float Un, Ue, Uw, Us;
    45     float Wn, We, Ww, Ws;
    46     float Hon, Hoe, How, Hos;
    47     float Hoo;
    48     int iteration = 500;
    49     while(iteration)
    50     {
    51         for (i = 1; i < M - 1; i++)
    52         {
    53             for (j = 1; j < N - 1; j++)
    54             {
    55                 if (((char *)(mask->imageData + i * mask->widthStep))[j] < 0)//坏损区
    56                 {
    57                     UO = ((float*)(void*)(src->data.ptr + (size_t)src->step*i))[j];
    58                     UN = ((float*)(void*)(src->data.ptr + (size_t)src->step*(i-1)))[j];
    59                     US = ((float*)(void*)(src->data.ptr + (size_t)src->step*(i+1)))[j];
    60                     UE = ((float*)(void*)(src->data.ptr + (size_t)src->step*i))[j+1];
    61                     UW = ((float*)(void*)(src->data.ptr + (size_t)src->step*i))[j-1];
    62
    63                     UNE = ((float*)(void*)(src->data.ptr + (size_t)src->step*(i-1)))[j+1];
    64                     UNW = ((float*)(void*)(src->data.ptr + (size_t)src->step*(i-1)))[j-1];
    65                     USE = ((float*)(void*)(src->data.ptr + (size_t)src->step*(i+1)))[j+1];
    66                     USW = ((float*)(void*)(src->data.ptr + (size_t)src->step*(i+1)))[j-1];
    67
    68                     Un = sqrt((UO - UN) * (UO - UN) + ((UNW - UNE) / 2.0) * ((UNW - UNE) / 2.0));
    69                     Ue = sqrt((UO - UE) * (UO - UE) + ((UNE - USE) / 2.0) * ((UNE - USE) / 2.0));
    70                     Uw = sqrt((UO - UW) * (UO - UW) + ((UNW - USW) / 2.0) * ((UNW - USW) / 2.0));
    71                     Us = sqrt((UO - US) * (UO - US) + ((USW - USE) / 2.0) * ((USW - USE) / 2.0));
    72
    73                     Wn = 1.0/sqrt(Un * Un + delta * delta);
    74                     We = 1.0/sqrt(Ue * Ue + delta * delta);
    75                     Ww = 1.0/sqrt(Uw * Uw + delta * delta);
    76                     Ws = 1.0/sqrt(Us * Us + delta * delta);
    77
    78                     Hon = Wn/(Wn+We+Ww+Ws+lambda);
    79                     Hoe = We/(Wn+We+Ww+Ws+lambda);
    80                     How = Ww/(Wn+We+Ww+Ws+lambda);
    81                     Hos = Ws/(Wn+We+Ww+Ws+lambda);
    82
    83                     Hoo = lambda/(Wn+We+Ww+Ws+lambda);
    84                     ((float*)(void*)(src->data.ptr + (size_t)src->step*i))[j]=(Hon*UN+Hoe*UE+How*UW+Hos*US+Hoo*UO);
    85                 }
    86             }
    87         }
    88         iteration--;
    89     }
    90     cvConvert(src, src_uint8);
    91     t = ((double)getTickCount() - t)/getTickFrequency();
    92     printf("算法用时:%f秒\n", t);
    93     cvShowImage("修复结果", src_uint8);
    94     cvWaitKey(0);
    95 }

由于迭代次数和浮点数的运算,使得算法时间较长,效果如下,仔细观察可以看出仍有细节处修复效果不是很理想。在TV模型之后,又出现了许多改进的TV模型,在速度和效果上都比理想,此处不深入探讨。

转载于:https://www.cnblogs.com/hxjbc/p/6675901.html

图像修复中的TV模型相关推荐

  1. 【图像修复】浅析:图像修复中的TV模型

    前言:图像修复是一项非常有意义的研究工作,比如我们生活中的照片被污染,再比如名贵字画.国家文物壁画等珍贵物品被破坏,这些都需要图像修复工作来完成. 简介:整体变分(Total Variation)的方 ...

  2. cdd 变分 图像修复 matlab,图像修复中的TV模型

    前言:图像修复是一项非常有意义的研究工作,比如我们生活中的照片被污染,再比如名贵字画.国家文物壁画等珍贵物品被破坏,这些都需要图像修复工作来完成. 简介:整体变分(Total Variation)的方 ...

  3. 图像修复中的方法--AI智能.

    [编者按]近些年,基于深度学习的发展,计算机视觉在人工智能和深度学习的大背景下方兴未艾,与此同时,当越来越多的应用场景被挖掘出来时,也意味着计算机视觉的发展前景将无比广阔,其中图像处理技术就是最热门的 ...

  4. 图像算法原理与实践——图像修复之 全变分模型

    在图像算法的高层次处理中,有一类很典型的应用,就是图像修复算法.图像在采集.传输.预处理过程中,都可能会发生图像数据被修改.损失和缺失等问题(例如:部分图像内容被污染.雾霾等),另外,在实际室外拍照的 ...

  5. 图像算法原理与实践——图像修复之全变分模型

    在图像算法的高层次处理中,有一类很典型的应用,就是图像修复算法.图像在采集.传输.预处理过程中,都可能会发生图像数据被修改.损失和缺失等问题(例如:部分图像内容被污染.雾霾等),另外,在实际室外拍照的 ...

  6. 深度图像修复的一个突破

    作者:Chu-Tak Li 编译:ronghuaiyang(AI 公园) 导读 使用上下文注意力来进行深度图像修复. 今天,我们将深入探讨深度图像修复的一个突破,上下文注意力.通过使用上下文注意力,我 ...

  7. 深度图像修复的回顾和改进:使用生成对抗网络基于Patch的图像修复

    点击上方"AI公园",关注公众号,选择加"星标"或"置顶" 作者:Chu-Tak Li 编译:ronghuaiyang 导读 相比于之前,在 ...

  8. Matlab图像处理笔记--图像修复

    大多数的修图软件都是通过借用相邻像素内容来对照片进行处理,这其中比较有代表性的就要数Adobe的修图软件了,但这这种方式也有一定的缺陷,就是当你的图像变成这个样子时,那么这张照片就彻底没救了,如下图所 ...

  9. 图像修复必读的10篇论文

    点击上方"AI公园",关注公众号,选择加"星标"或"置顶" 因公众号更改了推送规则,记得读完点"在看"~下次AI公园的新 ...

最新文章

  1. Spring boot定时任务(Scheduling Tasks)
  2. 关于烂代码的那些事(中)
  3. Java并发编程(一)线程的各种创建方式
  4. Dotnet 2.0配置系统
  5. Java核心技术及面试指南 异常部分的面试题归纳以及答案
  6. java面试题44关于 Socket 通信编程,以下描述正确的是:( )
  7. android wear 2 手表,Android Wear 2.0 和新款智能手表有望在2月8号发布
  8. 2021-10-13企业财务数据风险预警之随机森林
  9. jframe大小根据组件变化_Swing JDialog容器和JFrame容器使用教程
  10. css四种定位及相关知识总结(附实例、图解)
  11. java c 引用类型_C++引用类型详解
  12. 使用Word 2003“格式→外文版式→带圈字符”功能可以输入10以上带圈序号。
  13. SQL Server 数据库之启动 SQL Server 2008 服务
  14. Java 实现加减乘除
  15. VB——消费记录及查询系统。
  16. @PageableDefault
  17. csdn博客使用反馈,bug
  18. java io流分为,Java中的IO流按照传输数据不同,可分为和
  19. 域名 超过注册日两年_域名 – “注册商注册过期日期”与实际到期日之间的关系...
  20. 字体感觉小了 引入的vant_vue-cli3中vant字体库改为本地引入

热门文章

  1. rmi远程代码执行漏洞_【漏洞通告】Apache Solr远程代码执行漏洞
  2. 不止面试题,笔记源码统统都有
  3. 怎样获取网站的域名_深入挖掘同行,厉害的人是怎样做的?
  4. 数字经济时代下老年群体手机APP软件网络推广适老化需求日益明显
  5. 网络营销重点之如何了解用户需求完善网络营销策略
  6. 网站增改不要只想着收益更应该思考原有的损失
  7. 网站优化中站点为什么会出现404页面?
  8. 作为SEO老人不轻易建议客户进行动态网页优化设置
  9. oracle 实现HA,oracle RAC的客户端HA配置
  10. 求助matlab分解质因数,Matlab