zoukankan      html  css  js  c++  java
  • 学习图像处理,从C++编程开始

         最近学习遇到瓶颈,主要是编程水平和专业知识跟不上,发现学习图像处理、模式识别,一开始真不能死钻在一个点上不放,还是要尽可能拓展知识面,包括扎实的数学基础,数学分析,概率论,线性代数,常微分方程,运筹学,控制论,复变函数与积分变换这些学科还是得好好学一下,泛函分析,时间序列,小波分析,抽象代数,分形理论也得有一定了解,对基本的数值分析方法和现代优化算法需要熟练掌握,还有常用的机器学习算法。。。顿时又倍感鸭梨>_<

        不过看了一堆最近的招聘信息,最基本的还是要先把编程搞搞好,尤其是C++,同时每天坚持学习理论知识。于是今天开始又翻开C++ primer,发现学编程语言就是个死循环,不管这个函数体有多长。

        先从编译器开始学起,在网上找到一个介绍GCC不错的文章,和大家share一下,也督促自己每天坚持学习,坚持写博客!

        原文来自http://pinseng.blog.sohu.com/36877994.html

    DSP(digital singnal
    processor)是一种独特的微处理器,是以数字信号来处理大量信息的器件。其工作原理是接收模拟信号,转换为0或1的数字信号,再对数字信号进行修改、删除、强化,并在其他系统芯片中把数字数据解译回模拟数据或实际环境格式。它不仅具有可编程性,而且其实时运行速度可达每秒数以千万条复杂指令程序,远远超过通用微处理器,是数字化电子世界中日益重要的电脑芯片。它的强大数据处理能力和高运行速度,是最值得称道的两大特色。

    DSP芯片,也称数字信号处理器,是一种特别适合于进行数字信号处理运算的微处理器具,其主机应用是实时快速地实现各种数字信号处理算法。根据数字信号处理的要求,DSP芯片一般具有如下主要特点:


    (1)在一个指令周期内可完成一次乘法和一次加法;
    (2)程序和数据空间分开,可以同时访问指令和数据;

    (3)片内具有快速RAM,通常可通过独立的数据总线在两块中同时访问;
    (4)具有低开销或无开销循环及跳转的硬件支持;

    (5)快速的中断处理和硬件I/O支持;
    (6)具有在单周期内操作的多个硬件地址产生器;
    (7)可以并行执行多个操作;

    (8)支持流水线操作,使取指、译码和执行等操作可以重叠执行。

    当然,与通用微处理器相比,DSP芯片的其他通用功能相对较弱些。



    GNU 工程 开始于一九八四年,旨在发展一个类似 Unix ,且为自由软件的完整操作系统.


    详细介绍:
    GNU计划,是由Richard
    Stallman在1983年9月27日公开发起的。它的目标是创建一套完全自由的操作系统。Richard
    Stallman最早是在net.unix-wizards新闻组上公布该消息,并附带一份《GNU宣言》等解释为何发起该计划的文章,其中一个理由就是要“重现当年软件界合作互助的团结精神”。


    GNU工程已经开发了一个被称为“GNU”(GNU 是由“GNU's Not
    Unix”所递回定义出的首字母缩写语;它的发音为“guh-NEW”)的、对Unix向上兼容的完整的自由软件系统(free software
    system)。由Richard
    Stallman完成的最初的GNU工程的文档被称为‘GNU宣言’,该宣言已经被翻译成多种其它语言。我们还有创作与1983年的GNU工程创始宣言。


    在1983年构思GNU工程是为了提供一种找回在计算机界早期的盛行的合作精神的方式--为了使合作成为可能而排除有私有软件所有者给合作造成的障碍。


    在1971年,当Richard
    Stallman开始他在MIT的职业生涯时,他工作于一个专门使用自由软件的工作组。即使计算机公司也经常发布自由软件。程序员可以自由地相互合作,就象他们通常所作的那样。


    到了80年代,几乎所有的软件都是私有的,这意味着它有一个不允许并且预防用户合作的拥有者。这就使得GNU工程成为必要的了。


    每个计算机的使用者都需要一个操作系统;如果没有自由的操作系统,那么如果你不求助于私有软件,你甚至不能开始使用一台计算机。所以自由软件议事日程的第一项就是自由的操作系统。


    一个操作系统不仅仅是一个内核;它还包括编译器、编辑器、文本排版程序,电子邮件软件,和许多其他东西。因此,创作一个完整的操作系统是一项十分庞大的工作。它将耗费太多的年头。


    由于Unix的全局设计已经得到认证并且广泛流传,我们决定使操作系统与Unix兼容。同时这种兼容性使Unix的使用者可以容易地转移到GNU上来。


    自由的,类似于Unix的内核的初始目标已经达到了。到90年代,我们已经发现或者完成了除了内核之外的所有主要成分。而Linux,一个自由的内核,由Linus
    Torvalds开发了。把Linux和几乎完成的GNU
    系统结合起来,就构成了一个完整的操作系统:一个基于Linux的GNU系统。估计目前大约有十万人在使用基于Linux的GNU系统,包括Slackware、Debian、Red
    Hat以及其它。


    然而,GNU工程并不限于操作系统。我们的目标是提供所有类型的软件,无论有多少用户需要它。这包括了应用软件。我们已经有了电子表格。我们希望在未来把GNU
    Emacs扩展为所见即所得的桌面出版系统。

    我们还想为不是计算机专家的用户提供软件。为此我们正在创作‘拖放图标桌面’以帮助初学者使用
    GNU系统。

    我们还希望提供游戏和其它娱乐。已经由一些游戏可以使用了。


    自由软件可以走多远?这没有限制,除非诸如版权法之类的法律完全地禁止自由软件。最终的目的是,让自由软件完成计算机用户希望完成的所有工作--从而导致自由软件的过时。



    GCC


    Linux系统下的Gcc(GNU C
    Compiler)是GNU推出的功能强大、性能优越的多平台编译器,是GNU的代表作品之一。gcc是可以在多种硬体平台上编译出可执行程序的超级编译器,其执行效率与一般的编译器相比平均效率要高20%~30%。

    Gcc编译器能将C、C++语言源程序、汇程式化序和目标程序编译、连接成可执行文件,如果没有给出可执行文件的名字,gcc将生成一个名为a.out的文件。在Linux系统中,可执行文件没有统一的后缀,系统从文件的属性来区分可执行文件和不可执行文件。而gcc则通过后缀来区别输入文件的类别,下面我们来介绍gcc所遵循的部分约定规则。

    .c为后缀的文件,C语言源代码文件;
    .a为后缀的文件,是由目标文件构成的档案库文件;
    .C,.cc或.cxx
    为后缀的文件,是C++源代码文件;
    .h为后缀的文件,是程序所包含的头文件;
    .i 为后缀的文件,是已经预处理过的C源代码文件;

    .ii为后缀的文件,是已经预处理过的C++源代码文件;
    .m为后缀的文件,是Objective-C源代码文件;

    .o为后缀的文件,是编译后的目标文件;
    .s为后缀的文件,是汇编语言源代码文件;
    .S为后缀的文件,是经过预编译的汇编语言源代码文件。

    Gcc的执行过程

    虽然我们称Gcc是C语言的编译器,但使用gcc由C语言源代码文件生成可执行文件的过程不仅仅是编译的过程,而是要经历四个相互关联的步骤∶预处理(也称预编译,Preprocessing)、编译(Compilation)、汇编(Assembly)和连接(Linking)。

    命令gcc首先调用cpp进行预处理,在预处理过程中,对源代码文件中的文件包含(include)、预编译语句(如宏定义define等)进行分析。接着调用cc1进行编译,这个阶段根据输入文件生成以.o为后缀的目标文件。汇编过程是针对汇编语言的步骤,调用as进行工作,一般来讲,.S为后缀的汇编语言源代码文件和汇编、.s为后缀的汇编语言文件经过预编译和汇编之后都生成以.o为后缀的目标文件。当所有的目标文件都生成之后,gcc就调用ld来完成最后的关键性工作,这个阶段就是连接。在连接阶段,所有的目标文件被安排在可执行程序中的恰当的位置,同时,该程序所调用到的库函数也从各自所在的档案库中连到合适的地方。


    Gcc的基本用法和选项

    在使用Gcc编译器的时候,我们必须给出一系列必要的调用参数和文件名称。Gcc编译器的调用参数大约有100多个,其中多数参数我们可能根本就用不到,这里只介绍其中最基本、最常用的参数。

    Gcc最基本的用法是∶gcc [options] [filenames]

    其中options就是编译器所需要的参数,filenames给出相关的文件名称。

    -c,只编译,不连接成为可执行文件,编译器只是由输入的.c等源代码文件生成.o为后缀的目标文件,通常用于编译不包含主程序的子程序文件。
    -o
    output_filename,确定输出文件的名称为output_filename,同时这个名称不能和源文件同名。如果不给出这个选项,gcc就给出预设的可执行文件a.out。

    -g,产生符号调试工具(GNU的gdb)所必要的符号资讯,要想对源代码进行调试,我们就必须加入这个选项。

    -O,对程序进行优化编译、连接,采用这个选项,整个源代码会在编译、连接过程中进行优化处理,这样产生的可执行文件的执行效率可以提高,但是,编译、连接的速度就相应地要慢一些。

    -O2,比-O更好的优化编译、连接,当然整个编译、连接过程会更慢。

    -Idirname,将dirname所指出的目录加入到程序头文件目录列表中,是在预编译过程中使用的参数。C程序中的头文件包含两种情况∶

    A)#include
    B)#include “myinc.h”
    其中,A类使用尖括号(< >),B类使用双引号(“
    ”)。对于A类,预处理程序cpp在系统预设包含文件目录(如/usr/include)中搜寻相应的文件,而对于B类,cpp在当前目录中搜寻头文件,这个选项的作用是告诉cpp,如果在当前目录中没有找到需要的文件,就到指定的dirname目录中去寻找。在程序设计中,如果我们需要的这种包含文件分别分布在不同的目录中,就需要逐个使用-I选项给出搜索路径。

    -Ldirname,将dirname所指出的目录加入到程序函数档案库文件的目录列表中,是在连接过程中使用的参数。在预设状态下,连接程序ld在系统的预设路径中(如/usr/lib)寻找所需要的档案库文件,这个选项告诉连接程序,首先到-L指定的目录中去寻找,然后到系统预设路径中寻找,如果函数库存放在多个目录下,就需要依次使用这个选项,给出相应的存放目录。

    -lname,在连接时,装载名字为“libname.a”的函数库,该函数库位于系统预设的目录或者由-L选项确定的目录下。例如,-lm表示连接名为“libm.a”的数学函数库。

    上面我们简要介绍了gcc编译器最常用的功能和主要参数选项,更为详尽的资料可以参看Linux系统的联机帮助。

    假定我们有一个程序名为test.c的C语言源代码文件,要生成一个可执行文件,最简单的办法就是∶
    gcc test.c

    这时,预编译、编译连接一次完成,生成一个系统预设的名为a.out的可执行文件,对于稍为复杂的情况,比如有多个源代码文件、需要连接档案库或者有其他比较特别的要求,就要给定适当的调用选项参数。再看一个简单的例子。

    整个源代码程序由两个文件testmain.c
    和testsub.c组成,程序中使用了系统提供的数学库,同时希望给出的可执行文件为test,这时的编译命令可以是∶
    gcc testmain.c
    testsub.c lm o test
    其中,-lm表示连接系统的数学库libm.a。

    Gcc的错误类型及对策

    Gcc编译器如果发现源程序中有错误,就无法继续进行,也无法生成最终的可执行文件。为了便于修改,gcc给出错误资讯,我们必须对这些错误资讯逐个进行分析、处理,并修改相应的语言,才能保证源代码的正确编译连接。gcc给出的错误资讯一般可以分为四大类,下面我们分别讨论其产生的原因和对策。


    第一类∶C语法错误
    错误资讯∶文件source.c中第n行有语法错误(syntex
    errror)。这种类型的错误,一般都是C语言的语法错误,应该仔细检查源代码文件中第n行及该行之前的程序,有时也需要对该文件所包含的头文件进行检查。有些情况下,一个很简单的语法错误,gcc会给出一大堆错误,我们最主要的是要保持清醒的头脑,不要被其吓倒,必要的时候再参考一下C语言的基本教材。

    第二类∶头文件错误
    错误资讯∶找不到头文件head.h(Can not find include file
    head.h)。这类错误是源代码文件中的包含头文件有问题,可能的原因有头文件名错误、指定的头文件所在目录名错误等,也可能是错误地使用了双引号和尖括号。


    第三类∶档案库错误
    错误资讯∶连接程序找不到所需的函数库,例如∶
    ld: -lm: No such file or
    directory

    这类错误是与目标文件相连接的函数库有错误,可能的原因是函数库名错误、指定的函数库所在目录名称错误等,检查的方法是使用find命令在可能的目录中寻找相应的函数库名,确定档案库及目录的名称并修改程序中及编译选项中的名称。

    第四类∶未定义符号
    错误资讯∶有未定义的符号(Undefined
    symbol)。这类错误是在连接过程中出现的,可能有两种原因∶一是使用者自己定义的函数或者全局变量所在源代码文件,没有被编译、连接,或者干脆还没有定义,这需要使用者根据实际情况修改源程序,给出全局变量或者函数的定义体;二是未定义的符号是一个标准的库函数,在源程序中使用了该库函数,而连接过程中还没有给定相应的函数库的名称,或者是该档案库的目录名称有问题,这时需要使用档案库维护命令ar检查我们需要的库函数到底位于哪一个函数库中,确定之后,修改gcc连接选项中的-l和-L项。

    排除编译、连接过程中的错误,应该说这只是程序设计中最简单、最基本的一个步骤,可以说只是开了个头。这个过程中的错误,只是我们在使用C语言描述一个算法中所产生的错误,是比较容易排除的。我们写一个程序,到编译、连接通过为止,应该说刚刚开始,程序在运行过程中所出现的问题,是算法设计有问题,说得更玄点是对问题的认识和理解不够,还需要更加深入地测试、调试和修改。一个程序,稍为复杂的程序,往往要经过多次的编译、连接和测试、修改。下面我们学习的程序维护、调试工具和版本维护就是在程序调试、测试过程中使用的,用来解决调测阶段所出现的问题。

  • 相关阅读:
    Apache Spark 2.2.0 中文文档
    Apache Spark 2.2.0 中文文档
    Apache Spark 2.2.0 中文文档
    Apache Spark 2.2.0 中文文档
    Apache Spark 2.2.0 中文文档
    Apache Spark RDD(Resilient Distributed Datasets)论文
    Apache Spark 2.2.0 中文文档
    Apache Spark 2.2.0 中文文档
    【机器学习实战】第10章 K-Means(K-均值)聚类算法
    [译]flexbox全揭秘
  • 原文地址:https://www.cnblogs.com/mlv5/p/2016351.html
Copyright © 2011-2022 走看看