• 【步步为营】尝试亲手编写数字图像处理软件的乐趣,构建属于你的MagicHouse 【循序渐进】逐层探秘...【深入浅出并重,理论同实践共举】全面介绍Visualc++环境下进行数字图像处理编程的开发利器:DIB、GDI+和OpenCV
  • 本文系《数字图像处理原理与实践(MATLAB版)》一书的勘误表。 【内容简介】本书全面系统地介绍了数字图像处理技术的理论方法,内容涉及几何变换、灰度变换、图像增强、图像分割、图像去噪、小波变换、形态学...

    本文系《数字图像处理原理与实践(MATLAB版)》一书的勘误表。

    【内容简介】本书全面系统地介绍了数字图像处理技术的理论与方法,内容涉及几何变换、灰度变换、图像增强、图像分割、图像去噪、小波变换、形态学处理、多尺度融合、偏微分方程应用、正交变换与图像压缩、边缘及轮廓检测、图像复原、图像去雾、多尺度空间构建与特征匹配等15大核心话题。所有算法均配有完整的MATLAB实现代码,并以此为基础详细介绍了MATLAB中与图像处理有关的近200个函数的使用方法,便于读者学习与实践。此外,本书还提供了丰富的在线支持资源,方便为读者答疑解惑及提供辅助资料下载。

    【选购链接】京东当当亚马逊

     

     

    1、P21,  则MATLAB会显示行运行的结果。

    应该改为:则MATLAB会显示该行运行的结果。

     

    2、P38,代码部分中 i = imread('theatre.jpg') 应该改为 a =  imread('theatre.jpg') 

     

    3、P39,   d 为线性函数在y轴上的斜率... ... 

    应该改为: d 为线性函数在y轴上的截距... ...

     

    4、P129,单调性中的公式有误,原文是:

    应该改为:

     

    5、P177,原文中的公式:ρ = y sinθ + y cosθ 有误

    应该改为:ρ = y sinθ + x cosθ

     

    6、第31页第一段,最后一句,''建议读者可以参阅参考文献[2]和[4]以获得更多相关信息'',

    应该改为:''建议读者可以参阅参考文献[2]和[3]以获得更多相关信息'',

     

     

    7、第386页,公式 有误

     

    应该改为:

     

    8、第126页,“因此B1位置像素值将被置为1”,应该改为:

    因此B2位置像素值将被置为1

     

    9、第2章,2.2.3小节中,“产生的图像几乎全黑”,应该改为:

    “产生的图像几乎全白”

     

    10、第142页,公式有误。

    最右侧的一对儿括号内的 加号“+”,应该改为减号 “-”。

     

    如果你在阅读本书过程中,发现任何问题,也欢迎反馈给我(可以在本博客留言或者发邮件给我),感谢你为本书的改进所做的贡献。

     

     

     

    展开全文
  • 本文系《数字图像处理原理与实践(MATLAB版)》一书之代码系列的Part1(P1~42),代码执行结果请参见原书配图。     P20   I = imread('lena.jpg'); BW1 = im2bw(I); BW2 = im2bw(I, 0.3); BW3 = im2bw(I, ...

    本文系《数字图像处理原理与实践(MATLAB版)》一书之代码系列的Part1(P1~42),代码执行结果请参见原书配图。

     

     

    P20

     

    I = imread('lena.jpg');
    BW1 = im2bw(I);
    BW2 = im2bw(I, 0.3);
    BW3 = im2bw(I, 0.6);
    figure
    subplot(2,2,1),imshow(I);
    title('original');
    subplot(2,2,2),imshow(BW1);
    title('\default');
    subplot(2,2,3),imshow(BW2);
    title('level = 0.3');
    subplot(2,2,4),imshow(BW3);
    title('level = 0.6')

     

    P25-1

     

    IMG1 = imread('airplane.jpg');
    IMG2 = imread('baboon.jpg');
    IMG3 = imread('lena.jpg');
    imshow(IMG1)
    imshow(IMG2)
    imshow(IMG3)

     

    P25-2

     

    % figure
    imshow(IMG1)
    figure(5)
    imshow(IMG2)

     

    P26

     

    figure;
    subplot(1,2,1),subimage(IMG1);
    title('airplane');
    subplot(1,2,2),subimage(IMG2);
    title('baboon');

     

    P31

     

    imhist(I)
    imhist(I, n)
    [counts, x]=imhist(...)

     

    P32

     

    i = imread('theatre.jpg');
    g = rgb2gray(i);
    figure
    subplot(121), imhist(g);
    subplot(122), imhist(g, 64);

     

    P33

     

    i = imread('baboon.jpg');
    i = rgb2gray(i);
    [m,n]=size(i);
    [counts1, x]=imhist(i, 32);
    subplot(121), stem(x, counts1);
    counts2 = counts1/m/n;
    subplot(122), stem(x, counts2);

     

    P35

     

    i=imread('theatre.jpg');
    [x,y,z]=size(i);

    figure
    subplot(221), imshow(i);
    title('original image')

    %提取红色分量
    r=i;
    %r(:,:,1)=a(:,:,1);
    r(:,:,2)=zeros(x,y);
    r(:,:,3)=zeros(x,y);
    r=uint8(r);
    subplot(222),imshow(r);
    title('R-component-image')

    %提取绿色分量
    g=i;
    g(:,:,1)=zeros(x,y);
    %g(:,:,2)=a(:,:,2);
    g(:,:,3)=zeros(x,y);
    g=uint8(g);
    subplot(223),imshow(g);
    title('G-component-image')

    %提取蓝色分量
    b=i;
    b(:,:,1)=zeros(x,y);
    b(:,:,2)=zeros(x,y);
    %b(:,:,3)=a(:,:,3);
    b=uint8(b);
    subplot(224),imshow(b);
    title('B-component-image')

     

     P38

     

    i=imread('theatre.jpg');
    r=i(:,:,1);
    g=i(:,:,2);
    b=i(:,:,3);
    subplot(1,3,1), imhist(r), title('R component');
    subplot(1,3,2), imhist(g), title('G component');
    subplot(1,3,3), imhist(b), title('B component');


     

    P41

     

    i = imread('theatre.jpg');
    i = im2double(rgb2gray(i));
    [m,n]=size(i);

    %增加对比度
    Fa = 1.25; Fb = 0;
    O = Fa.*i + Fb/255;
    figure(1), subplot(221), imshow(O);
    title('Fa = 1.25, Fb = 0, contrast increasing');
    figure(2),subplot(221), [H,x]=imhist(O, 64);
    stem(x, (H/m/n), '.');
    title('Fa = 1.25, Fb = 0, contrast increasing');

    %减小对比度
    Fa =0.5; Fb = 0;
    O = Fa.*i + Fb/255;
    figure(1), subplot(222),imshow(O);
    title('Fa = 0.5, Fb = 0, contrast decreasing');
    figure(2), subplot(222), [H,x] = imhist(O, 64);
    stem(x, (H/m/n), '.');
    title('Fa = 0.5, Fb = 0, contrast decreasing');

    %线性亮度增加
    Fa = 0.5; Fb = 50;
    O = Fa.*i + Fb/255;
    figure(1), subplot(223), imshow(O);
    title('Fa = 0.5, Fb = 50, brightness control');
    figure(2), subplot(223), [H,x]=imhist(O,64);
    stem(x, (H/m/n), '.');
    title('Fa = 0.5, Fb = 50, brightness control');

    %反相显示
    Fa = -1; Fb = 255;
    O = Fa.*i + Fb/255;
    figure(1), subplot(224), imshow(O);
    title('Fa = -1, Fb = 255, reversal processing');
    figure(2), subplot(224),[H,x]=imhist(O, 64);
    stem(x, (H/m/n), '.');
    title('Fa = -1, Fb = 255, reversal processing');

     

    (代码发布未完,请待后续...)

     

     

    展开全文
  • 全是书中源代码,非常详细
  •   <br />  数字图像处理原理与实践:基于Visual C++开发 左飞 万晋森 刘航 著 ISBN 978-7-121- 12776-2 2011年4月出版 定价:89.00元(含光盘1张) 16开 652 ...

     

    封面

     

    数字图像处理原理与实践:基于Visual C++开发
    左飞  万晋森  刘航  著
    ISBN 978-7-121- 12776-2
    2011年4月出版
    定价:89.00元(含光盘1张)
    16开
    652 页
    宣传语
    《Visual C++数字图像处理开发入门与编程实践》原书最新升级版
    步步为营  循序渐进  全新升级 
    深入与浅出并重,理论同实践共举
    内 容 简 介
    本书全面系统地讲述了在Visual C++环境下进行数字图像处理编程的技术和方法。全书共分成14章,针对数字图像处理领域中的核心话题,如色彩空间、图像文件格式、图像的点运算、图像的几何变换、图像的增强处理、边缘检测和轮廓跟踪、图像形态学、图像分割、图像加密等,进行了详细的介绍。另外,针对Visual C++ 2005下的数字图像处理开发,本书还对设备无关位图、图形设备接口、OpenCV及ImageMagick等在实际开发中常用的具体技术进行了讲解,并辅以大量实例代码,具有很强的参考价值。
    本书兼有源于实践、贴近应用、深入浅出、通俗易懂的优点,又紧跟时代脉搏,牢牢把握最新技术方向,从案例出发强调新环境下的新方法。本书内容实用、体例新颖,既可以作为希望进行数字图像处理学习和研究的初学者的自学教材,也可作为大专院校计算机及相关专业师生或工程技术人员的参考书。
    谈治学——代序
    自世界上第一台电子计算机问世以来,现代计算机科学已经走过了极为不平凡的六十余年辉煌历程。有时想想,自己不禁感叹,相对于已经发展了几十年甚至上百年的任意一门学科,我们的学习过程实在太短暂了。要充分理解一个领域,时间显然是不够的,更何况现在学科门类越分越细,学科交叉现象越来越多,因此我们往往要同时面对多个领域。如果你是一名研究生或者博士生,有时也许可能会感到自己已经对某个领域“观其大略、略有小成”。其实自己是否真的已经达到这种状态并不重要,因为几年之后,当我们再回想起来,或许自然就会感到当时的稚气而不失活泼的劲头。如果现在,你的这种感觉愈发强烈,那么说明你在自己研究的这个方向上已经有了不小的长进。
    有人说自己“学得越多就会感到懂得越少,知道得越多就会感到理解得越少”,其实说的就是自己在不停地进步。在现行学习的各种情境下,大家都变得匆忙起来,匆忙的人容易被欺骗,于是我们会听信一些自己或别人有限理解下的狭隘看法,甚至我们会将这些看法作为一种基点,甚至会看成是一种准则。就像现在每天网络上都会有海量信息向我们涌来,尽管没有人会对网上的言论负责,但我们确实很容易在不经意之间将浏览网页时看到的一条难辨真伪的消息迅速地、不假思索地照单全收、信以为真。于是现在漫天飞舞的那些关于某位明星突然病故的谣言才会如此神速地传播开来。八卦谣言如此,学术研究更是如此。这其实也没什么,重要的是我们不能让这种看法伤害到自己及自己努力的脚步。
    大家都会写论文、看论文。看论文讲求看高质量的,这是当然。我们也无非是想在前人的基础上做出一点点创新工作。前人的理论结果在这短暂的过程与浩瀚的领域下似乎只是偏离及错误的程度不同,因为论文是在搞研究,是一些还未出现的假想的规则,或是一些假想的解决方案。它们基于的都是另一些研究的成果,“踩在别人的肩膀上,肩膀在哪并不重要,是不是巨人的也不重要,只要以后有人踩踩自己的肩膀就行了”,在这种情况下对与错、是与非、准确与偏离的界限也越来越朦胧。
    有时会觉得别人的做法、方式、结果其实并不好。有时甚至会认为其实对与错并不那么重要,它只是在很多条件、环境、约束下的一种看法。人们所做的事情—只是让周围最值得注意的一类人群尽可能满意就已经很好了。现在的媒体、老师,甚至一些同学我觉得都已经具备了一种令人惊叹而又平凡的能力,那就是“可以把白的说成黑的,紧接着在情况不对时,又可以再把黑的说成白的”这种能力。有人对肖氏反射弧提出质疑,发明人就会不惜触犯法律的威严拿起铁棒还对方以颜色。一方面是把白的说成了黑的,而另一方面大部分人选择了默认,欣然接受了指鹿为马的事实。而对于我们每个人,说到底最重要的还是要抓紧时间“多走一点路”,用不断前进的脚步走出各种环境,使自己不用沦落到非得用“把白说成黑”这种三流手段去骗取点什么的地步,更重要的是使别人在把白说成黑的时候,我们依然能够保持一份清醒。
    感慨了这么多,写在我新书的最前面,真诚地希望本书的读者能够把如何治学这个问题想个清楚明白。若能如此,我想正在看本书的你定能在自己所从事的领域中有所收获、有所成绩。
    前    言
    大约两年多前,我同万晋森、刘航合作编写了《Visual C++数字图像处理开发入门与编程实践》(电子工业出版社出版)一书。作为一本在Visual C++环境下讲解数字图像处理开发的方法与技术的书籍,该书赢得了颇佳的口碑。许多读者纷纷来信,无论是对书品的褒奖,还是与我们探讨技术问题,都令我们为之鼓舞。
    有鉴于《Visual C++数字图像处理开发入门与编程实践》所取得的不错成绩,电子工业出版社的有关编辑建议我们紧跟时代步伐与技术发展趋势,适时对原书进行修订以期再版。经过一番思度与商讨,我们决定结合第一版书的读者反馈并联系技术发展的最新动向,以原书为基础重新著书立说,于是便有了这本《数字图像处理原理与实践:基于Visual C++开发》。
    脱胎于原书的改版本,一方面保持了前作通俗易懂、理论联系实际的风格,另一方面,我们也进行了大胆的调整,删减了一些比较基础性的导引篇幅和相对比较陈旧的内容,同时增补了一些更新颖的话题及更丰富的实例。
    近年来,随着研究的不断深入,数字图像处理应用也日益广泛,这使得数字图像处理的广度和难度不断加强,但同时对于初学者的学习带来了相当的困难。观察现有的众多数字图像处理书籍,大部分教材注重图像处理理论的阐述,而在一定程度上忽略了这些理论的应用和实现。另外,对于一些实例教程,虽然重视了代码的实现,却在算法的描述和扩展上略有欠缺。这使得读者很难通过一本书比较全面地了解和掌握数字图像处理的基础内容。
    为此,尽可能通俗地为读者描述图像处理算法的原理和实现手段,并为读者提供翔实可靠的实现代码,确保每一个读者都能理解和掌握,始终都是我们在创作过程中最大的考量。本书系统地介绍了应用Visual C++进行数字图像处理编程的基本思路和方法,采用案例为主的叙述方式,将大量的技术理论融入具体的案例剖析中。涉及数字图像处理领域中十余个重要主题,提供了近百个具体算法的实现源码,代码总量有数万行之多。
    总的来说,本书依然本色地保持了前作中体现出来的几个有别于其他同类书籍的优点。
    首先,与集成开发环境深度结合。在深入剖析MFC机制的同时将丰富的图像处理与编程实现融为一体。
    其次,叙述过程中始终不脱离实践这个主题,每章都设置相应的实例带动读者进行学习。穿插于书中的实例为本书的一大特色。这些实例大都为时下流行的图像处理软件的某个具体模块或部分的实现,实例原型十分常见。这些巧妙新颖的实例将使枯燥乏味的理论变得妙趣横生。全书实例都在Visual Studio 2005下调试通过,读者可以在随书光盘中获得有关源码。
    最后,笔者自主编写了一个扩展性良好的数字图像处理算法试验平台Magic House。Magic House不仅完整实现了一款普通数字图像处理软件应具备的基本功能,而且它框架清晰、容易理解,非常适合读者学习。我们也看到,前作出版后其他作者跟风出版的一些数字图像处理作品中有严重抄袭和剽窃Magic House的现象发生,但作为Magic House的原创者,没有哪本书能够比我们更透彻地向读者介绍这个软件的架构与实现。
    除了传承前作的优点之外,本版又有哪些变化呢?
    首先,本版增加了对部分复杂算法的更为细致的讲解与描述,同时也丰富了前作的实例代码资源。
    其次,本书增加了一些包括图像加密(特别是图像的混沌加密)等在内的前沿话题,为有志在此发展的读者提供了独一无二的资源。
    最后,除了前作中介绍到的DIB、GDI+和OpenCV,本版中还增加了对ImageMagick的介绍。作为近年来发展和流行起来的数字图像处理库,ImageMagick已经受到广大开发者的青睐,但目前国内尚无对它的相关资料出版,这也是本版中的一个亮点。
    我们都知道,数字图像处理是一门飞速发展的技术。国内大部分数字图像处理教材都长期不更新,而且同类书籍千篇一律,很多读者迫于无奈,只能在许许多多陈旧不堪的内容上翻来覆去。因此,我们也希望能够为这个领域的后来者抛砖引玉,为同类书籍注入一丝清新的空气。
    本书前一版本承蒙多位专家指导与帮助,其中西北工业大学计算机学院博士生导师王庆教授审阅了本书前版并提出了宝贵的意见和建议,西北工业大学计算机学院冯萍教授对本书前版的写作给予了诚恳的支持,中国科学院高级工程师、技术作家白乔博士在我的创作过程中始终鼎力相助。这里,再次向他们表示最诚挚的感谢。另外,我的两位合作者—网易游戏的万晋森与腾讯科技的刘航—在技术方面一直都非常令我钦佩,他们在百忙之中与我一道编写此书,令我深感振奋。正是由于有了他们的加盟,本书才得以付梓,也感谢他们为本书作付出的一切!最后,我也要感谢本书第一版的读者朋友们,他们诚恳的意见与建议使得新版更加精进、更加完美,给予我们的鼓励也一直驱使着我们前行。
    由于时间仓促,纰漏和欠缺之处在所难免,言语之中有失偏颇之处,还望读者不吝赐教和批评。联系信箱:fzuo@yahoo.cn

    左 飞   
    2010年12月
    于珠水之滨

    展开全文
  • 本文系《数字图像处理原理与实践(MATLAB版)》一书之代码系列的Part3,辑录该书第135至第184页之代码,供有需要读者下载研究使用。代码执行结果请参见原书配图。     ---------------------------------------...

     

    本文系《数字图像处理原理与实践(MATLAB版)》一书之代码系列的Part3,辑录该书第135至第184页之代码,供有需要读者下载研究使用。代码执行结果请参见原书配图。

     

     

    -------------------------------------------

     

     

    P139

     

     

    original = imread('snowflakes.png');
    figure, imshow(original);
    se = strel('disk',5);
    afterOpening = imopen(original,se);
    figure, imshow(afterOpening,[]);


    P140

     

     

     

    originalBW = imread('circles.png');
    imshow(originalBW);
    se = strel('disk',10);
    closeBW = imclose(originalBW,se);
    figure, imshow(closeBW)

     


    P144

     

     

     

     

    bw = imread('bw.bmp');
    shape1 = [0 0 0 0 1
                0 0 0 1 1
                0 0 1 1 1
                0 1 1 1 1
                1 1 1 1 1];
    shape2 = [1 1 0 0 0
                1 0 0 0 0
                0 0 0 0 0
                0 0 0 0 0
                0 0 0 0 0];
    bw2 = bwhitmiss(bw, shape1, shape2);
    imshow(bw2)

     


    P146-1

     

     

     

     

    I = imread('letter2.jpg');
    I = im2bw(I);
    I1 = bwmorph(I, 'thin',inf);
    figure(1), imshow(I1);

     


    P146-2

     

     

     

     

    I = imread('letter2.jpg');
    I = im2bw(I);
    I2 = bwmorph(I, 'skel',inf);
    figure(2), imshow(I2);

     


    P153

     

     

     

     

    I = imread('lena.jpg');
    I = rgb2gray(I);
    BW1 = edge(I, 'roberts');
    BW2 = edge(I, 'sobel');
    BW3 = edge(I, 'prewitt');
    figure
    subplot(2,2,1),imshow(I),title('original')
    subplot(2,2,2),imshow(BW1),title('roberts')
    subplot(2,2,3),imshow(BW2),title('sobel')
    subplot(2,2,4),imshow(BW3),title('prewitt')

     


    P157

     

     

     

     

    I = imread('einstein.bmp');
    I = rgb2gray(I);
    N = [1, 2, 1
         0, 0, 0
         -1,-2,-1];
    edge_n = imfilter(I,N,'symmetric','conv');
    imwrite(edge_n, 'edge_n.jpg');

     


    P160

     

     

     

     

    I = rgb2gray(imread('lena.jpg'));
    M = [1,1,1
            1,-8,1
            1,1,1];
    img=imfilter(I,M);
    [x,y]=size(I);
    img2 = img;
    for i = 2:x-1
            for j = 2:y-1
                a = [img(i,j+1),img(i,j-1),img(i+1,j+1),img(i+1,j-1), ...
                     img(i-1,j+1),img(i-1,j-1),img(i+1,j),img(i-1,j)];
                if ( (max(a)-min(a))>64 && max(a)>img(i,j) && min(a)<img(i,j))
                    img2(i,j)=255;
                else
                    img2(i,j)=0;
                end
            end
    end

     


    P165

     

     

     

     

    I = imread('lena.jpg');
    IMG = rgb2gray(I);
    Edge_LoG = edge(IMG, 'log');
    imshow(Edge_LoG);
    figure
    subplot(1,2,1), imshow(IMG);
    subplot(1,2,2), imshow(Edge_LoG);

     


    P167

     

     

    I = double(rgb2gray(imread('lena.jpg')));
    figure, imshow(uint8(I))
    DoG=fspecial('gaussian',5,0.8)-fspecial('gaussian',5,0.6);
    ImageDoG=imfilter(I,DoG,'symmetric','conv');
    figure, imshow(ImageDoG)
    % threshold = 2
    proc_Img1 = ImageDoG;
    proc_Img1(find(proc_Img1 < 2))=0;
    figure, imshow(proc_Img1)
    % threshold = 3
    proc_Img2 = ImageDoG;
    proc_Img2(find(proc_Img2 < 3))=0;
    figure, imshow(proc_Img2)


    P172

     

     

     

    img = edge(I, 'canny',[0.032,0.08], 3);

     


    P183

     

     

     

     

    RGB= imread('building.jpg');
    I = rgb2gray(RGB);
    BW = edge(I, 'canny');
    
    [H, T, R]=hough(BW, 'RhoResolution',0.5,'ThetaResolution',0.5);
    figure, imshow(imadjust(mat2gray(H)), 'XData', T, ...
    'YData', R, 'InitialMagnification', 'fit');
    xlabel('\theta'), ylabel('\rho');
    axis on; axis normal; hold on;
    colormap(hot);
    peaks = houghpeaks(H, 15);
    figure, imshow(BW);
    hold on;
    lines = houghlines(BW, T, R, peaks, 'FillGap',25, 'MinLength',15);
    
    max_len = 0;
    for k=1:length(lines)
    xy = [lines(k).point1; lines(k).point2];
       plot(xy(:,1),xy(:,2),'LineWidth',3,'Color','b');
       plot(xy(1,1),xy(1,2),'x','LineWidth',3,'Color','yellow');
       plot(xy(2,1),xy(2,2),'x','LineWidth',3,'Color','red');
    
       len = norm(lines(k).point1 - lines(k).point2);
       if ( len > max_len)
          max_len = len;
          xy_long = xy;
       end
    end

     

    -------------------------------------------

     

    原书184页,我曾提到,MATLAB中图像处理工具箱提供的Hough直线检测的效果不是特别好,并推荐了一个我个人认为实现得更好的版本。但由于本人并非该代码之原作者,遂未将其收录于书中。近来有读者留言,希望可以获得这部分代码,所以我特将其发布到此博客上,供有需要的读者参考学习。

     

    代码原作者为Tao Peng,请尊重原作者权利。

     

    %  Author:  Tao Peng  
    %           Department of Mechanical Engineering  
    %           University of Maryland, College Park, Maryland 20742, USA  
    %           pengtao@glue.umd.edu  
    %  Version: alpha       Revision: Dec. 02, 2005


    使用时可参考下面这两个例子:

     

     

    % EXAMPLE #1:  
    rawimg = imread('TestHT_Chkbd1.bmp');  
    fltr4img = [1 2 3 2 1; 2 3 4 3 2; 3 4 6 4 3; 2 3 4 3 2; 1 2 3 2 1];  
    fltr4img = fltr4img / sum(fltr4img(:));  
    imgfltrd = filter2( fltr4img , rawimg );  
      
      
    [accum, axis_rho, axis_theta, lineprm, lineseg] = Hough_Grd(imgfltrd, 6, 0.02);  
      
    figure(1); imagesc(axis_theta*(180/pi), axis_rho, accum); axis xy;  
    xlabel('Theta (degree)'); ylabel('Pho (pixels)');  
    title('Accumulation Array from Hough Transform');  
    figure(2); imagesc(rawimg); colormap('gray'); axis image;  
    DrawLines_2Ends(lineseg);  
    title('Raw Image with Line Segments Detected'); 

     

    函数Houg_Grd()代码实现:

     

        function [accum, axis_rho, axis_theta, varargout] = ...  
            Hough_Grd(img, varargin)  
        %Detect lines in a grayscale image  
        %  
        %  [accum, axis_rho, axis_theta, lineprm, lineseg, dbg_label] =  
        %      Hough_Grd(img, grdthres, detsens)  
        %  Hough transform for line detection based on image's gradient field.  
        %  NOTE:    Operates on grayscale images, NOT B/W bitmaps.  
        %           NO loops involved in the implementation of Hough transform,  
        %               which makes the operation fast.  
        %           Able to detect the two ends of line segments.  
        %  
        %  INPUT: (img, grdthres, detsens)  
        %  img:         A 2-D grayscale image (NO B/W bitmap)  
        %  grdthres:    (Optional, default is 8, must be non-negative)  
        %               The algorithm is based on the gradient field of the  
        %               input image. A thresholding on the gradient magnitude  
        %               is performed before the voting process of the Hough  
        %               transform to remove the 'uniform intensity' (sort-of)  
        %               image background from the voting process. In other words,  
        %               pixels with gradient magnitudes smaller than 'grdthres'  
        %               are considered not belong to any line.  
        %  detsens:     (Optional, default is 0.08)  
        %               A value that controls the sensitivity of line detection.  
        %               The range of the value is from 0 to 1, open ends.  
        %               Although the physical meaning of this parameter is not  
        %               obvious, it controls the algorithm in a fuzzy manner.  
        %               The SMALLER the value is, the MORE features in the image  
        %               will be considered as lines.  
        %  
        %  OUTPUT: [accum, axis_rho, axis_theta, lineprm, lineseg, dbg_label]  
        %  accum:       The result accumulation array from the Hough transform.  
        %               The horizontal dimension is 'theta' and the vertical  
        %               dimension is 'rho'.  
        %  axis_rho:    Vector that contains the 'rho' values for the rows in  
        %               the accumulation array.  
        %  axis_theta:  Vector that contains the 'theta' values for the columns  
        %               in the accumulation array.  
        %  lineprm:     (Optional)  
        %               Parameters (rho, theta) of the lines detected. Is a N-by-2  
        %               matrix with each row contains the parameters (rho, theta)   
        %               for a line. The definitions of 'rho' and 'theta' are as  
        %               the following:  
        %               'rho' is the perpendicular distance from the line to the  
        %               origin of the image. 'rho' can be negative since 'theta'  
        %               is constrained to [0, pi]. The unit of 'rho' is in pixels.  
        %               'theta' is the sweep angle from axis X (i.e. horizontal  
        %               axis of the image) to the direction that is perpendicular  
        %               to the line. The range of 'theta' is [0, pi].  
        %  lineseg:     (Optional)  
        %               Parameters (x1, x2, y1, y2) of line segments detected.  
        %               Lines given by (rho, theta) are infinite lines. This  
        %               function tries to detect line segments in the raw image  
        %               and output them as 'lineseg', which is a Ns-by-4 matrix  
        %               with each row contains the parameters (x1, x2, y1, y2)  
        %               that defines the two ends of a line segment.  
        %  dbg_label:   (Optional, for debug purpose)  
        %               Labelled segmentation map from the search of peaks in  
        %               the accumulation array  
        %  
        %  
        %  BUG REPORT:  
        %  This is an alpha version. Please send your bug reports, comments and  
        %  suggestions to pengtao@glue.umd.edu . Thanks.  
          
        %  Reserved for extension  
        %  accumres:    (Optional, default is [4, 1], minimum is [2, 0.5])  
        %               The desired resolutions in 'rho' and 'theta'. Is a  
        %               2-element vector in following format:  
        %               [resolution in 'rho' (pixels),  
        %               resolution in 'theta' (degrees)]  
          
          
          
          
        %%%%%%%% Arguments and parameters %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  
          
        % Validation of arguments  
        if ndims(img) ~= 2 || ~isnumeric(img),  
            error('Hough_Grd: ''img'' has to be 2 dimensional');  
        end  
        if ~all(size(img) >= 16),  
            error('Hough_Grd: ''img'' has to be larger than 16-by-16');  
        end  
          
          
        % Parameters (default values)  
        prm_grdthres = 8;  
        prm_accumres = [4, 1];  
        prm_detsens = 0.08;  
          
          
        func_compu_lineprm = true;  
        prm_fltraccum = true;  
          
          
        % Validation of arguments  
        vap_grdthres = 1;  
        if nargin > vap_grdthres,  
            if isnumeric(varargin{vap_grdthres}) && ...  
                    varargin{vap_grdthres}(1) >= 0,  
                prm_grdthres = varargin{vap_grdthres}(1);  
            else  
                error(['Hough_Grd: ''grdthres'' has to be ', ...  
                    'a non-negative number']);  
            end  
        end  
        %{  
        vap_accumres = 3;  
        if nargin > vap_accumres,  
            if numel(varargin{vap_accumres}) == 2 && ...  
                    isnumeric(varargin{vap_accumres}) && ...  
                    ( varargin{vap_accumres}(1) >= 2 && ...  
                    varargin{vap_accumres}(2) >= 0.5 ),  
                prm_accumres = varargin{vap_accumres};  
            else  
                error(['Hough_Grd: ''accumres'' has to be a two-element ', ...  
                    'vector and no smaller than [2, 0.5]']);  
            end  
        end  
        %}  
        vap_detsens = 2;  
        if nargin > vap_detsens,  
            if isnumeric(varargin{vap_detsens}) && ...  
                    varargin{vap_detsens}(1) > 0 && varargin{vap_detsens}(1) < 1,  
                prm_detsens = varargin{vap_detsens};  
            else  
                error('Hough_Grd: ''detsens'' has to be in the range (0, 1)');  
            end  
        end  
          
          
        func_compu_lineprm = ( nargout > 3 );  
          
          
        % Size of the accumulation array  
        imgsize = size(img);  
        coef_rhorng = [ -imgsize(2), sqrt(sum(imgsize.^2)) ];  
        coef_thetarng = [-pi/18, pi+pi/18];  
          
          
        prm_accumsize = [ ...  
            round( (coef_rhorng(2)-coef_rhorng(1)) * (2/prm_accumres(1)) ) , ...  
            round( (coef_thetarng(2)-coef_thetarng(1)) * (180/pi) * ...  
            (2/prm_accumres(2)) ) ];  
          
          
        % Default filter for the accumulation array  
        prm_acmfltr_R = 4;  
        prm_acmfltr_w = [1 2 4 8];  
          
          
        fltr4accum = ones(2 * prm_acmfltr_R - 1) * prm_acmfltr_w(1);  
        for k = 2 : prm_acmfltr_R,  
            fltr4accum(k:(2*prm_acmfltr_R-k), k:(2*prm_acmfltr_R-k)) = ...  
                prm_acmfltr_w(k);  
        end  
        fltr4accum = fltr4accum / sum(fltr4accum(:));  
          
          
        % Parameters for the algorithm using repeated  
        % thresholding and segmentation  
        prm_lp_dthres = min([ 0.1, (0.1+prm_detsens)/2 ]);  
        prm_lp_maxthres = 0.8;  
          
          
        % Parameters for the algorithm using local maximum filter  
        prm_useaoi = false;  
        prm_aoiminsize = [8, 8];  
          
          
        prm_fltrLM_R = 4;  
        prm_fltrLM_s = 1.3;  
        prm_fltrLM_r = ceil( prm_fltrLM_R * 0.6 );  
        prm_fltrLM_npix = 6;  
          
          
        % Reserved parameters  
        dbg_on = false;      % debug information  
        dbg_bfigno = 5;  
        if nargout > 5,  dbg_on = true;  end  
          
          
          
          
        %%%%%%%% Building accumulation array %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  
          
          
        % Compute the gradient and the magnitude of gradient  
        img = double(img);  
        [grdx, grdy] = gradient(img);  
        grdmag = sqrt(grdx.^2 + grdy.^2);  
          
          
        % Clear the margins of the gradient field  
        prm_grdfldmgn = 4;  
        grdmag([1:prm_grdfldmgn, (end-prm_grdfldmgn+1):end], :) = 0;  
        grdmag(:, [1:prm_grdfldmgn, (end-prm_grdfldmgn+1):end]) = 0;  
          
          
        % Get the linear indices, as well as the subscripts, of the pixels  
        % whose gradient magnitudes are larger than the given threshold  
        grdmasklin = find(grdmag > prm_grdthres);  
        [grdmask_IdxI, grdmask_IdxJ] = ind2sub(imgsize, grdmasklin);  
          
          
        % Compute (the line parameter) 'theta' for all voting pixels  
        grdphs_vot = atan2( grdy(grdmasklin), grdx(grdmasklin) );  
          
          
        % -- Regulate 'grdphs_vot' from [-pi, pi] to [0, pi]  
        grdphs_vot = grdphs_vot + pi * (grdphs_vot < 0);  
          
          
        % Compute the 'theta'-subscript (to the accumulation array)  
        % for all voting pixels  
        coef_subtheta = prm_accumsize(2) / ...  
            (coef_thetarng(2) - coef_thetarng(1)) * (1 - 1e-6);  
        sub_theta = ceil( (grdphs_vot - coef_thetarng(1)) * coef_subtheta );  
          
          
        % 'theta' vector for the accumulation array  
        axis_theta = (coef_thetarng(1) + 0.5 / coef_subtheta) : ...  
            (1 / coef_subtheta) : coef_thetarng(2);  
          
          
        % Compute the 'rho' values for all voting pixels  
        % rho = (J - 0.5) * cos(theta) + (I - 0.5) * sin(theta)  
        rho_vot = (grdmask_IdxJ - 0.5) .* cos(grdphs_vot) + ...  
            (grdmask_IdxI - 0.5) .* sin(grdphs_vot);  
          
          
        % Compute the 'rho'-subscript (to the accumulation array)  
        % for all voting pixels  
        coef_subrho = prm_accumsize(1) / ...  
            (coef_rhorng(2) - coef_rhorng(1)) * (1 - 1e-6);  
        sub_rho = ceil( (rho_vot - coef_rhorng(1)) * coef_subrho );  
          
          
        % 'rho' vector for the accumulation array  
        axis_rho = (coef_rhorng(1) + 0.5 / coef_subrho) : ...  
            (1 / coef_subrho) : coef_rhorng(2);  
          
          
        % Build the accumulation array, using gradient magnitude as weight  
        accum = accumarray( sub2ind(prm_accumsize, sub_rho, sub_theta), ...  
            grdmag(grdmasklin) );  
        accum = [ accum ; ...  
            zeros(prm_accumsize(1) * prm_accumsize(2) - numel(accum), 1) ];  
        accum = reshape( accum, prm_accumsize );  
          
          
          
          
        %%%%%%%% Locating peaks in the accumulation array %%%%%%%%%%%%%%%%%%%  
          
          
        % Stop if no need to estimate the parameters of the lines  
        if ~func_compu_lineprm,  
            return;  
        end  
          
          
        % Smooth the accumulation array  
        if prm_fltraccum,  
            accum = filter2( fltr4accum, accum );  
        end  
          
          
        % Find the maximum value in the accumulation array  
        accum_max = max(accum(:));  
          
          
          
          
        %------- Algorithm 1: Local maximum filter (begin) -------------  
        % Build the local maximum filter  
        fltr4LM = zeros(2 * prm_fltrLM_R + 1);  
          
          
        [mesh4fLM_x, mesh4fLM_y] = meshgrid(-prm_fltrLM_R : prm_fltrLM_R);  
        mesh4fLM_r = sqrt( mesh4fLM_x.^2 + mesh4fLM_y.^2 );  
        fltr4LM_mask = ...  
            ( mesh4fLM_r > prm_fltrLM_r & mesh4fLM_r <= prm_fltrLM_R );  
        fltr4LM = fltr4LM - ...  
            fltr4LM_mask * (prm_fltrLM_s / sum(fltr4LM_mask(:)));  
          
          
        if prm_fltrLM_R >= 4,  
            fltr4LM_mask = ( mesh4fLM_r < (prm_fltrLM_r - 1) );  
        else  
            fltr4LM_mask = ( mesh4fLM_r < prm_fltrLM_r );  
        end  
        fltr4LM = fltr4LM + fltr4LM_mask / sum(fltr4LM_mask(:));  
          
          
        % Select a number of Areas-Of-Interest from the accumulation array  
        if prm_useaoi,  
            % Thresholding and segmentation  
            accummask = ( accum > (accum_max * prm_detsens) );  
            [accumlabel, accum_nRgn] = bwlabel( accummask, 8 );  
          
          
            % Select AOIs from segmented regions  
            accumAOI = ones(0,4);  
            for k = 1 : accum_nRgn,  
                accumrgn_lin = find( accumlabel == k );  
                [accumrgn_IdxI, accumrgn_IdxJ] = ...  
                    ind2sub( size(accumlabel), accumrgn_lin );  
                rgn_top = min( accumrgn_IdxI );  
                rgn_bottom = max( accumrgn_IdxI );  
                rgn_left = min( accumrgn_IdxJ );  
                rgn_right = max( accumrgn_IdxJ );          
                % The AOIs selected must satisfy a minimum size  
                if ( (rgn_bottom - rgn_top + 1) >= prm_aoiminsize(1) || ...  
                        (rgn_right - rgn_left + 1) >= prm_aoiminsize(2) ),  
                    accumAOI = [ accumAOI; ...  
                        max([ 1, rgn_top - prm_fltrLM_R ]), ...  
                        min([ size(accum,1), rgn_bottom + prm_fltrLM_R ]), ...  
                        max([ 1, rgn_left - prm_fltrLM_R ]), ...  
                        min([ size(accum,2), rgn_right + prm_fltrLM_R ]) ];  
                end  
            end  
        else  
            % Whole accumulation array as the one AOI  
            accumAOI = [1, size(accum,1), 1, size(accum,2)];  
        end  
          
          
        % **** Debug code (begin)  
        if dbg_on && prm_useaoi,  
            dbg_accumLM = zeros(size(accum));  
        end  
        % **** Debug code (end)  
          
          
        % For each of the AOIs selected, locate the local maxima  
        lineprm = zeros(0,2);  
        for k = 1 : size(accumAOI, 1),  
            aoi = accumAOI(k,:);    % just for referencing convenience  
          
          
            % Apply the local maxima filter  
            candLM = conv2( accum(aoi(1):aoi(2), aoi(3):aoi(4)) , ...  
                fltr4LM , 'same' );  
          
          
            % Thresholding of 'candLM' & 'accum'  
            if prm_useaoi,  
                candLM_mask = ( candLM > (max(candLM(:))*prm_detsens) & ...  
                    accummask(aoi(1):aoi(2),aoi(3):aoi(4)) );  
            else  
                candLM_mask = ( candLM > (max(candLM(:))*prm_detsens) & ...  
                    accum(aoi(1):aoi(2),aoi(3):aoi(4)) > (accum_max*prm_detsens) );  
            end  
          
          
            % Clear the margins of 'candLM_mask'  
            candLM_mask([1:prm_fltrLM_R, (end-prm_fltrLM_R+1):end], :) = 0;  
            candLM_mask(:, [1:prm_fltrLM_R, (end-prm_fltrLM_R+1):end]) = 0;  
          
          
            % **** Debug code (begin)  
            if dbg_on && prm_useaoi,  
                dbg_accumLM(aoi(1):aoi(2), aoi(3):aoi(4)) = ...  
                    dbg_accumLM(aoi(1):aoi(2), aoi(3):aoi(4)) + candLM;  
            end  
            % **** Debug code (end)  
          
          
            % Group the local maxima candidates by adjacency, compute the  
            % centroid position for each group and take that as the center  
            % of one circle detected  
            [candLM_label, candLM_nRgn] = bwlabel( candLM_mask, 8 );  
          
          
            for ilabel = 1 : candLM_nRgn,  
                % Indices (to current AOI) of the pixels in the group  
                candgrp_masklin = find( candLM_label == ilabel );  
                [candgrp_IdxI, candgrp_IdxJ] = ...  
                    ind2sub( size(candLM_label) , candgrp_masklin );  
          
          
                % Indices (to 'accum') of the pixels in the group  
                candgrp_IdxI = candgrp_IdxI + ( aoi(1) - 1 );  
                candgrp_IdxJ = candgrp_IdxJ + ( aoi(3) - 1 );  
                candgrp_idx2acm = ...  
                    sub2ind( size(accum) , candgrp_IdxI , candgrp_IdxJ );  
          
          
                % Minimum number of qulified pixels in the group  
                if sum(numel(candgrp_masklin)) < prm_fltrLM_npix,  
                    continue;  
                end  
          
          
                % Compute the centroid position  
                candgrp_acmsum = sum( accum(candgrp_idx2acm) );  
                cc_rho = sum( candgrp_IdxI .* accum(candgrp_idx2acm) ) / ...  
                    candgrp_acmsum;  
                cc_theta = sum( candgrp_IdxJ .* accum(candgrp_idx2acm) ) / ...  
                    candgrp_acmsum;  
                lineprm = [lineprm; cc_rho, cc_theta];  
            end  
        end  
          
          
        % **** Debug code (begin)  
        if dbg_on,  
            figure(dbg_bfigno);  
            if prm_useaoi,  
                imagesc(dbg_accumLM); axis xy;  
            else  
                imagesc(candLM); axis xy;  
            end  
        end  
        % **** Debug code (end)  
        %------- Algorithm 1: Local maximum filter (end) ---------------  
          
          
        %------- Algo 2: Repeated thresholding & segmentation (begin) --  
        %{  
        % Locate the peaks (in pixel coordinates) in the accumulation array  
        if dbg_on,  
            [lineprm, dbg_label] = RecursSegment( accum , ...  
                accum_max * [prm_detsens, prm_lp_dthres, prm_lp_maxthres] );  
        else  
            lineprm = RecursSegment( accum , ...  
                accum_max * [prm_detsens, prm_lp_dthres, prm_lp_maxthres] );  
        end  
          
          
        % **** Debug code (begin)  
        if dbg_on,  
            figure(dbg_bfigno);  
            imagesc(dbg_label); axis xy; axis equal;  
            hold on;  
            plot(lineprm(:,2), lineprm(:,1), ...  
                'w+', 'LineWidth', 2, 'MarkerSize', 6);  
            hold off;  
        end  
        % **** Debug code (end)  
        %}  
        %------- Algo 2: Repeated thresholding & segmentation (end) ----  
          
          
          
          
        % Convert 'lineprm' from pixel coordinates to (rho, theta)  
        lineprm = [ (lineprm(:,1) - 0.5)/coef_subrho + coef_rhorng(1), ...  
            (lineprm(:,2) - 0.5)/coef_subtheta + coef_thetarng(1) ];  
          
          
        % Output 'lineprm'  
        varargout{1} = lineprm;  
        if nargout <= 4,  
            return;  
        end  
          
          
          
          
        %%%%%%%% Locating the line segments in the raw image %%%%%%%%%%%%%%%%  
          
          
        % Parameters for locating the line segments  
        prm_ls_tTol = [-pi/7.5, pi/7.5];  
        prm_ls_pTol = [-3.5, 3.5];  
        prm_ls_minlen = 10;  
          
          
        % Locate the two ends for all lines detected  
        rgnmask = logical(zeros(imgsize));  
        lineseg = zeros(0, 4);  
          
          
        for k = 1 : size(lineprm, 1),  
            % Compute the 'rho' values for all pixels voted,  
            % assuming they contribute to the current line  
            rho2_vot = (grdmask_IdxJ - 0.5) * cos( lineprm(k,2) ) + ...  
                (grdmask_IdxI - 0.5) .* sin( lineprm(k,2) );  
          
          
            % Find the pixels that belong to the line  
            PixOnLn_votmask = ( grdphs_vot > (lineprm(k,2) + prm_ls_tTol(1)) & ...  
                grdphs_vot < (lineprm(k,2) + prm_ls_tTol(2)) & ...  
                rho2_vot > (lineprm(k,1) + prm_ls_pTol(1)) & ...  
                rho2_vot < (lineprm(k,1) + prm_ls_pTol(2)) );  
          
          
            PixOnLn_lin = grdmasklin( find(PixOnLn_votmask) );  
            if isempty(PixOnLn_lin),  
                continue;  
            end  
            [PixOnLn_IdxI, PixOnLn_IdxJ] = ind2sub(imgsize, PixOnLn_lin);  
          
          
            % Find the axis-aligned bounding box for these pixels  
            bndbox = [ min(PixOnLn_IdxI), max(PixOnLn_IdxI), ...  
                min(PixOnLn_IdxJ), max(PixOnLn_IdxJ) ];  
          
          
            % Seperate the line segments by adjacencies  
            rgnmask( bndbox(1):bndbox(2), bndbox(3):bndbox(4) ) = 0;  
            rgnmask( PixOnLn_lin ) = 1;  
            [rgnlabel, nrgn] = bwlabel( ...  
                rgnmask(bndbox(1):bndbox(2), bndbox(3):bndbox(4)), 8 );  
          
          
            for k_rgn = 1 : nrgn,  
                % Get the linear indices of pixels that belong to one segment  
                seg_lin = find( rgnlabel == k_rgn );  
                [seg_IdxI, seg_IdxJ] = ind2sub( size(rgnlabel), seg_lin );  
          
          
                % Ignore if the line segment is too short  
                segspan = [ min(seg_IdxI) + bndbox(1) - 1, ...  
                    max(seg_IdxI) + bndbox(1) - 1, ...  
                    min(seg_IdxJ) + bndbox(3) - 1, ...  
                    max(seg_IdxJ) + bndbox(3) - 1 ];  
                if (segspan(2) - segspan(1) + 1) < prm_ls_minlen && ...  
                        (segspan(4) - segspan(3) + 1) < prm_ls_minlen,  
                    continue;  
                end  
          
          
                % Get the [x1 x2 y1 y2] structure for the line SEGMENT  
                if lineprm(k,2) > pi/4 && lineprm(k,2) < 3*pi/4,  
                    % ls_base_x = 0;  
                    ls_base_y = lineprm(k,1) / sin(lineprm(k,2));  
                    lineseg = [ lineseg; segspan(3) - 0.5, segspan(4) - 0.5, ...  
                        ls_base_y - (segspan(3) - 0.5) / tan(lineprm(k,2)), ...  
                        ls_base_y - (segspan(4) - 0.5) / tan(lineprm(k,2)) ];  
                else  
                    % ls_base_y = 0;  
                    ls_base_x = lineprm(k,1) / cos(lineprm(k,2));  
                    lineseg = [ lineseg; ...  
                        ls_base_x - (segspan(1) - 0.5) * tan(lineprm(k,2)), ...  
                        ls_base_x - (segspan(2) - 0.5) * tan(lineprm(k,2)), ...  
                        segspan(1) - 0.5, segspan(2) - 0.5 ];  
                end  
            end  
        end  
          
          
        % Output 'lineseg'  
        varargout{2} = lineseg;  
        if nargout > 5,  
            varargout{3} = dbg_label;  
        end  
          
          
          
          
          
          
        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  
        %%%%%%%% Recursive thresholding and segmentation ********************  
          
          
        function [lineprm, varargout] = RecursSegment(accum, struct_thres)  
        % 'struct_thres' contains [thres, deltathres, maxthres]  
        % 'lineprm' is in pixel coordinate (w.r.t. 'accum')  
          
          
        % Parameters  
        prm_as_minpixn = 3;  
        prm_as_maxsize = [12, 12];  
          
          
        % Thresholding  
        accummask = ( accum > struct_thres(1) );  
          
          
        % Segmentation and locating the centroids of individual regions  
        [accumlabel, accum_nRgn] = bwlabel( accummask, 8 );  
          
          
        % Segmentation label (for debug purpose)  
        func_seglbl = ( nargout > 1 );  
        if func_seglbl,  
            seglbl_lblshft = 4;  
            seglabel = accumlabel;  
        end  
          
          
        lineprm = zeros(0, 2);  
        for k = 1 : accum_nRgn,  
            % Linear indices of the pixels in one connected component  
            acmrgn_lin = find( accumlabel == k );  
            if numel(acmrgn_lin) < prm_as_minpixn,  
                continue;  
            end  
            % Subscripts of the pixels in one connected component  
            [acmrgn_IdxPho, acmrgn_IdxTheta] = ...  
                ind2sub( size(accumlabel), acmrgn_lin );  
          
          
            % Further segmentation if the connected region is too big, or  
            % computing the centroid of the region  
            % -- Axis-aligned bounding box for the region  
            bndbox = [ min(acmrgn_IdxPho), max(acmrgn_IdxPho), ...  
                min(acmrgn_IdxTheta), max(acmrgn_IdxTheta) ];  
          
          
            % -- Further segmentation  
            bAddCentrdOfRgn = true;  
            if ( (bndbox(2) - bndbox(1) + 1) > prm_as_maxsize(1) || ...  
                    (bndbox(4) - bndbox(3) + 1) > prm_as_maxsize(2) ) && ...  
                    (struct_thres(1) + struct_thres(2)) <= struct_thres(3),  
                if func_seglbl,  
                    [lineprm_sub, seglabel_sub] = RecursSegment( ...  
                        accum(bndbox(1):bndbox(2), bndbox(3):bndbox(4)), ...  
                        [struct_thres(1) + struct_thres(2), struct_thres(2:3)] );  
                    seglabel(bndbox(1):bndbox(2), bndbox(3):bndbox(4)) = ...  
                        seglabel(bndbox(1):bndbox(2), bndbox(3):bndbox(4)) + ...  
                        seglabel_sub + (seglabel_sub > 0) * seglbl_lblshft;  
                else  
                    lineprm_sub = RecursSegment( ...  
                        accum(bndbox(1):bndbox(2), bndbox(3):bndbox(4)), ...  
                        [struct_thres(1) + struct_thres(2), struct_thres(2:3)] );  
                end  
                if ~isempty(lineprm_sub),  
                    lineprm = [lineprm; lineprm_sub(:,1) + bndbox(1) - 1, ...  
                        lineprm_sub(:,2) + bndbox(3) - 1 ];  
                    bAddCentrdOfRgn = false;  
                end  
            end  
          
          
            % -- Computing the centroid of the whole region  
            if bAddCentrdOfRgn,  
                acmrgn_acmsum = sum( accum(acmrgn_lin) );  
                lp_IdxPho = sum( acmrgn_IdxPho .* accum(acmrgn_lin) ) / ...  
                    acmrgn_acmsum;  
                lp_IdxTheta = sum( acmrgn_IdxTheta .* accum(acmrgn_lin) ) / ...  
                    acmrgn_acmsum;  
                lineprm = [ lineprm; lp_IdxPho, lp_IdxTheta ];  
            end  
        end  
          
          
        % Output the segmentation label  
        if func_seglbl,  
            varargout{1} = seglabel;  
        end  
          
          
        function DrawLines_2Ends(lineseg, varargin)  
          
        hold on;  
        for k = 1 : size(lineseg, 1),  
            % The image origin defined in function '[...] = Hough_Grd(...)' is  
            % different from what is defined in Matlab, off by (0.5, 0.5).  
            if nargin > 1,  
                plot(lineseg(k,1:2)+0.5, lineseg(k,3:4)+0.5, varargin{1});  
            else  
                plot(lineseg(k,1:2)+0.5, lineseg(k,3:4)+0.5, 'LineWidth', 2);  
            end  
        end  
        hold off;  
          
          
        function DrawLines_Polar(imgsize, lineprm, varargin)  
          
        hold on;  
        line = zeros(2,2);  
        for k = 1 : size(lineprm, 1),  
            if lineprm(k,2) > pi/4 && lineprm(k,2) < 3*pi/4,  
                line(1,1) = 0;  
                line(1,2) = lineprm(k,1) / sin(lineprm(k,2));  
                line(2,1) = imgsize(2);  
                line(2,2) = line(1,2) - line(2,1) / tan(lineprm(k,2));  
            else  
                line(1,2) = 0;  
                line(1,1) = lineprm(k,1) / cos(lineprm(k,2));  
                line(2,2) = imgsize(1);  
                line(2,1) = line(1,1) - line(2,2) * tan(lineprm(k,2));  
            end  
            % The image origin defined in function '[...] = Hough_Grd(...)' is  
            % different from what is defined in Matlab, off by (0.5, 0.5).  
            line = line + 0.5;  
            % Draw lines using 'plot'  
            if nargin > 2,  
                plot(line(:,1), line(:,2), varargin{1});  
            else  
                plot(line(:,1), line(:,2));  
            end  
        end  
        hold off;  

     

     

    (代码发布未完,请待后续...)

     

     

     

     

    展开全文
  • 针对遥感数字图像处理中的具体问题,《遥感数字图像处理 实践与操作/高等学校教材》综合遥感原理数字图像处理的理论知识,借助遥感软件进行系统的实践训练,使读者掌握遥感数字图像处理的基本原理及操作过程,为...
  • 数字图像处理是指将图像信号转换成数字信号并利用计算机对其进行处理的过程。图像处理最早出现于 20 世纪 50 年代,当时的电子计算机已经发展到一定水平,人们开始利用计算机来处理图形和图像信息。数字图像处理作为...

      数字图像处理是指将图像信号转换成数字信号并利用计算机对其进行处理的过程。图像处理最早出现于 20 世纪 50 年代,当时的电子计算机已经发展到一定水平,人们开始利用计算机来处理图形和图像信息。数字图像处理作为一门学科大约形成于 20 世纪 60 年代初期。早期的图像处理的目的是改善图像的质量,它以人为对象,以改善人的视觉效果为目的。图像处理中,输入的是质量低的图像,输出的是改善质量后的图像,常用的图像处理方法有图像增强、复原、编码、压缩等。

    数字图像处理常用方法:

    1 )图像变换:由于图像阵列很大,直接在空间域中进行处理,涉及计算量很大。因此,往往采用各种图像变换的方法,如傅立叶变换、沃尔什变换、离散余弦变换等间接处理技术,将空间域的处理转换为变换域处理,不仅可减少计算量,而且可获得更有效的处理(如傅立叶变换可在频域中进行数字滤波处理)。目前新兴研究的小波变换在时域和频域中都具有良好的局部化特性,它在图像处理中也有着广泛而有效的应用。

    2 )图像编码压缩:图像编码压缩技术可减少描述图像的数据量(即比特数),以便节省图像传输、处理时间和减少所占用的存储器容量。压缩可以在不失真的前提下获得,也可以在允许的失真条件下进行。编码是压缩技术中最重要的方法,它在图像处理技术中是发展最早且比较成熟的技术。

    3 )图像增强和复原:图像增强和复原的目的是为了提高图像的质量,如去除噪声,提高图像的清晰度等。图像增强不考虑图像降质的原因,突出图像中所感兴趣的部分。如强化图像高频分量,可使图像中物体轮廓清晰,细节明显;如强化低频分量可减少图像中噪声影响。图像复原要求对图像降质的原因有一定的了解,一般讲应根据降质过程建立“降质模型”,再采用某种滤波方法,恢复或重建原来的图像。

    4 )图像分割:图像分割是数字图像处理中的关键技术之一。图像分割是将图像中有意义的特征部分提取出来,其有意义的特征有图像中的边缘、区域等,这是进一步进行图像识别、分析和理解的基础。虽然目前已研究出不少边缘提取、区域分割的方法,但还没有一种普遍适用于各种图像的有效方法。因此,对图像分割的研究还在不断深入之中,是目前图像处理中研究的热点之一。

    5 )图像描述:图像描述是图像识别和理解的必要前提。作为最简单的二值图像可采用其几何特性描述物体的特性,一般图像的描述方法采用二维形状描述,它有边界描述和区域描述两类方法。对于特殊的纹理图像可采用二维纹理特征描述。随着图像处理研究的深入发展,已经开始进行三维物体描述的研究,提出了体积描述、表面描述、广义圆柱体描述等方法。

    6 )图像分类(识别):图像分类(识别)属于模式识别的范畴,其主要内容是图像经过某些预处理(增强、复原、压缩)后,进行图像分割和特征提取,从而进行判决分类。图像分类常采用经典的模式识别方法,有统计模式分类和句法(结构)模式分类,近年来新发展起来的模糊模式识别和人工神经网络模式分类在图像识别中也越来越受到重视。

    图像的基本属性

       亮度:也称为灰度,它是颜色的明暗变化,常用 0 %~ 100 % ( 由黑到白 ) 表示。以下三幅图是不同亮度对比。

    亮度对图像色彩的影响

       对比度:是画面黑与白的比值,也就是从黑到白的渐变层次。比值越大,从黑到白的渐变层次就越多,从而色彩表现越丰富。

    对比度对图像色彩表现的影响

       直方图:表示图像中具有每种灰度级的象素的个数,反映图像中每种灰度出现的频率。图像在计算机中的存储形式,就像是有很多点组成一个矩阵,这些点按照行列整齐排列,每个点上的值就是图像的灰度值,直方图就是每种灰度在这个点矩阵中出现的次数。我们可以具体看一下下面两个不同图形的灰度直方图:

     

    直方图均衡化

       通过灰度变换将一幅图像转换为另一幅具有均衡直方图的图像,即在一定灰度范围内具有相同的象素点数的图像的过程。下面是直方图均衡化前后的图形变化以及直方图变化:

    图像的加减运算

       两幅图像的加减运算:对图像进行加减运算,就是将图像对应的存储矩形点列上的灰度值进行加减运算。图像相加可以将一幅图像的内容加到另一幅图像上,可以实现二次曝光,也可一对同一个场景的多幅图像求平均值,这样可以降低噪声。图像相减可以用于运动检测或去除图像中不需要的加性图案。

       图像的加法示例:图中运算为: (a)+(b)=(c)

    a
    b
    c

       图像的减法运算示例:图中运算为 (a)-(b)=(c)

    a
    b
    c

    图像的噪声

       图像的噪声:就像对于听觉而言,在打电话时对方说话我们有时候会听到很嘈杂的噪声,以至于听不清楚对方在说什么。同样的,对于图像,原本我们可以很清晰的看到一幅图像,但是有时候图像上会有一些我们不需要的图案,使我们无法很清楚的看清一幅图,这就是图像的噪声。

    常用的图像去噪声方法

       常用的去噪方法:主要是采用滤波器对带噪声图像进行滤波处理。

    带噪声的图
    算术平均滤波后的图
    中值滤波后的图
    无噪声图

     

     

    数字图像处理技术的应用

       随着计算机技术的发展,图像处理技术已经深入到我们生活中的方方面面,其中,在娱乐休闲上的应用已经深入人心。图像处理技术在娱乐中的应用主要包括:电影特效制作、电脑电子游戏、数码相机、视频播放、数字电视等

       电影特效制作:自从 20 世纪 60 年代以来,随着电影中逐渐运用了计算机技术,一个全新的电影世界展现在人们面前,这也是一次电影的革命。越来越多的计算机制作的图像被运用到了电影作品的制作中。其视觉效果的魅力有时已经大大超过了电影故事的本身。如今,我们已经很难发现在一部电影中没有任何的计算机数码元素。

       电脑电子游戏:电脑电子游戏的画面,是近年来电子游戏发展最快的部分之一。从 1996 年到现在,游戏画面的进步简直可以用突飞猛进来形容,随着图像处理技术的发展,众多在几年前无法想象的画面在今天已经成为了平平常常的东西。

       数码相机:所谓数码相机,是一种能够进行拍摄,并通过内部处理把拍摄到的景物转换成以数字格式存放图像的特殊照相机。与普通相机不同,数码相机并不使用胶片,而是使用固定的或者是可拆卸的半导体存储器来保存获取的图像。数码相机可以直接连接到计算机、电视机或者打印机上。在一定条件下,数码相机还可以直接接到移动式电话机或者手持 PC 机上。由于图像是内部处理的,所以使用者可以马上检查图像是否正确,而且可以立刻打印出来或是通过电子邮件传送出去。

       视频播放与数字电视:家庭影院中的 VCD , DVD 播放器和数字电视中,大量使用了视频编码解码等图像处理技术,而视频编码解码等图像处理技术的发展,也推动了视频播放与数字电视象高清晰,高画质发展。

    展开全文
  • 学习图像处理入门书籍及代码
  • 数字图像处理(MATLAB版) 作 者:(美)冈萨雷斯(Gonzalez.R.C.)等著,阮秋琦 等译 出版社:电子工业出版社 出版时间: 2005-9-1 第1章 绪言 1.1 背景知识 1.2 什么是数字图像处理 1.3 MATLAB和图像处理工具箱...
  • 本文件夹包含数字图像处理MATLAB版的中文高清pdf以及两篇数字图像算法处理文章总结,希望能满足您的需求,谢谢
  • 本文系《数字图像处理原理与实践(MATLAB版)》一书之代码系列的Part4(由于之前发布顺序调整,请读者注意页码标注而不要仅仅依据系列文章的标题编号),辑录该书第186至第280页之代码,供有需要读者下载研究使用。...
  • 本文系《数字图像处理原理与实践(MATLAB版)》(电子工业出版社)一书之代码系列的Part2(P43~P135),代码执行结果请参见原书配图。     ----------------------------   P44   i = imread('theatre.jpg...
  • 分享下北师大朱文泉老师编写的《遥感数字图像处理》方法与原理实践与操作,配套这MOOC上的视频教程,可以帮你快速入门遥感图像处理
  • 遥感数字图像处理.

    2020-07-14 23:31:27
    遥感数字图像处理.主要采用erdas软件进行处理,主要用于在校生的实习
  • 《遥感数字图像处理》是重庆大学出版社出版的图书,较为系统地讲述了遥感数字图像处理必备的基础知识,遥感图像预处理、增强处理、遥感图像的监督分类和非监督分类等基本理论。
  • 图像的中值滤波(消除少量离散噪声)—>孤立噪声点和稍密集的噪声点或稍大的噪声点也有很好的去除效果。 I2=medfilt2(I1,[m,n])(I1待处理矩阵,[m,n]模板大小) 统计排序滤波器:对采样窗口内的奇数个像素的...
  • 在这个看脸的时代,颜值... 随着台式计算机的处理能力日益增强,各种图像拍摄的设备(例如平板电脑、手机摄像头、数码相机、扫描仪等)的普及,以及互联网的加持,使得数字图像处理变得文字处理一样普及。本书就数字
  • 数字图像处理之直方图处理直方图处理概念直方图均衡化(Histogram Equalization)直方图规定化局部直方图处理 直方图处理概念 灰度级范围为[0,L-1]的数字图像的直方图是离散函数h(rk)=nk,其中rk是第k级灰度值,nk...
1 2 3 4 5 ... 20
收藏数 13,467
精华内容 5,386
关键字:

原理与实践 数字图像处理