老司机种菜


  • 首页

  • 分类

  • 关于

  • 归档

  • 标签

  • 公益404

  • 搜索

gradle系列之配置

发表于 2018-07-06 | 分类于 Gradle

AndroidStudio中build.gradle配置信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

// Top-level build file where you can add configuration options common to all sub-projects/modules.
// Gradle中可以使用“//”或“/**/”来添加注释,与Java类似。
// 根目录下的build.gradle用于添加子工程或模块共用的配置项。

// "buildscript"的类型为script block,而且是最上层的script block,用于配置Gradle的Project实例。其API文档为https://docs.gradle.org/current/dsl/org.gradle.api.Project.html#org.gradle.api.Project:buildscript(groovy.lang.Closure)
// 其余的根script block有"allprojects", "dependencies", "configurations"等,更多的可见https://docs.gradle.org/current/dsl/的“Build script structure”一节。
// Script Block是一种method的调用,传入的参数为configuration closure。执行后会对Project的属性进行配置。
// 此处的"buildscript"用于配置Project的build script的classpath。
buildscript {
// 如果需要的话,从https://jcenter.bintray.com/下载code reposities。
repositories {
jcenter()
}
// 定义classpath,gradle会从“repositories”中下载对应版本的Gradle。如果使用gradle wrapper的话,感觉这个配置会被忽略。Wrapper会自己去下载所使用的gradle版本。
dependencies {
classpath 'com.android.tools.build:gradle:2.1.3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
// 该配置会被应用到所有的子工程。
allprojects {
repositories {
jcenter()
}
}
// 运行gradle clean时,执行此处定义的task。
// 该任务继承自Delete,删除根目录中的build目录。
// 相当于执行Delete.delete(rootProject.buildDir)。
// gradle使用groovy语言,调用method时可以不用加()。
task clean(type: Delete) {
delete rootProject.buildDir
}

buildscript中的声明是gradle脚本自身需要使用的资源。可以声明的资源包括依赖项、第三方插件、maven仓库地址等。而在build.gradle文件中直接声明的依赖项、仓库地址等信息是项目自身需要的资源。

gradle是由groovy语言编写的,支持groovy语法,可以灵活的使用已有的各种ant插件、基于jvm的类库,这也是它比maven、ant等构建脚本强大的原因。虽然gradle支持开箱即用,但是如果你想在脚本中使用一些第三方的插件、类库等,就需要自己手动添加对这些插件、类库的引用。而这些插件、类库又不是直接服务于项目的,而是支持其它build脚本的运行。所以你应当将这部分的引用放置在buildscript代码块中。gradle在执行脚本时,会优先执行buildscript代码块中的内容,然后才会执行剩余的build脚本。

举个例子,假设我们要编写一个task,用于解析csv文件并输出其内容。虽然我们可以使用gradle编写解析csv文件的代码,但其实apache有个库已经实现了一个解析csv文件的库供我们直接使用。我们如果想要使用这个库,需要在gradle.build文件中加入对该库的引用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
buildscript {
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath 'org.apache.commons:commons-csv:1.0'
}
}
import org.apache.commons.csv.*
task printCSV() {
doLast {
def records = CSVFormat.EXCEL.parse(new FileReader('config/sample.csv'))
for (item in records) {
print item.get(0) + ' '
println item.get(1)
}
}
}

buildscript代码块中的repositories和dependencies的使用方式与直接在build.gradle文件中的使用方式几乎完全一样。唯一不同之处是在buildscript代码块中你可以对dependencies使用classpath声明。该classpath声明说明了在执行其余的build脚本时,class loader可以使用这些你提供的依赖项。这也正是我们使用buildscript代码块的目的。

而如果你的项目中需要使用该类库的话,就需要定义在buildscript代码块之外的dependencies代码块中。所以有可能会看到在build.gradle中出现以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
compile 'org.springframework.ws:spring-ws-core:2.2.0.RELEASE',
'org.apache.commons:commons-csv:1.0'
}
buildscript {
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath 'org.apache.commons:commons-csv:1.0'
}
}
import org.apache.commons.csv.*
task printCSV() {
doLast {
def records = CSVFormat.EXCEL.parse(new FileReader('config/sample.csv'))
for (item in records) {
print item.get(0) + ' '
println item.get(1)
}
}
}
依赖更新

项目依赖的远程包如果有更新,会有提醒或者自动更新吗? 不会的,需要你手动设置changing标记为true,这样gradle会每24小时检查更新,通过更改resolutionStrategy可以修改检查周期。

1
2
3
4
5
6
7
configurations.all {
// check for updates every build
resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
}
dependencies {
compile group: "group", name: "projectA", version: "1.1-SNAPSHOT", changing: true
}

之前上传aar同一版本到maven仓库,但依赖却没有更新,该怎么办呢?可以直接删除本地缓存,缓存在~/.gradle/caches目录下,删除缓存后,下次运行就会自动重新下载远程依赖了。

取消任务

项目构建过程中那么多任务,有些test相关的任务可能根本不需要,可以直接关掉,在build.gradle中加入如下脚本:

1
2
3
4
5
tasks.whenTaskAdded { task ->
if (task.name.contains('AndroidTest')) {
task.enabled = false
}
}

tasks会获取当前project中所有的task,enabled属性控制任务开关,whenTaskAdded后面的闭包会在gradle配置阶段完成。

加入任务

任务可以取消了,但还不尽兴啊,想加入任务怎么搞?前面讲了dependsOn的方法,那就拿过来用啊,但是原有任务的依赖关系你又不是很清楚,甚至任务名称都不知道,怎么搞?

比如我想在执行dex打包之前,加入一个hello任务,可以这么写:

1
2
3
4
5
6
7
8
9
10
11
afterEvaluate {
android.applicationVariants.each { variant ->
def dx = tasks.findByName("dex${variant.name.capitalize()}")
def hello = "hello${variant.name.capitalize()}"
task(hello) << {
println "hello"
}
tasks.findByName(hello).dependsOn dx.taskDependencies.getDependencies(dx)
dx.dependsOn tasks.findByName(hello)
}
}

afterEvaluate是什么鸟?你可以理解为在配置阶段要结束,项目评估完会走到这一步。

variant呢?variant = productFlavors+ buildTypes,所以dex打包的任务可能就是dexCommonDebug。

你怎么知道dex任务的具体名称?Android Studio中的Gradle Console在执行gradle任务的时候会有输出,可以仔细观察一下。

hello任务定义的这么复杂干啥?我直接就叫hello不行吗?不行,each就是遍历variants,如果每个都叫hello,多个variant都一样,岂不是傻傻分不清楚,加上variant的name做后缀,才有任务的区分。

关键来了,dx.taskDependencies.getDependencies(dx)会获取dx任务的所有依赖,让hello任务依赖dx任务的所有依赖,再让dx任务依赖hello任务,这样就可以加入某个任务到构建流程了,是不是感觉非常灵活。

我突然想到,用doFirst的方式加入一个action到dx任务中,应该也可以达到上面效果。

任务监听

你想知道每个执行任务的运行时间吗?你想知道每个执行任务都是干嘛的吗?把下面这段脚本加入build.gradle中即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class TimingsListener implements TaskExecutionListener, BuildListener {
private Clock clock
private timings = []

@Override
void beforeExecute(Task task) {
clock = new org.gradle.util.Clock()
}

@Override
void afterExecute(Task task, TaskState taskState) {
def ms = clock.timeInMs
timings.add([ms, task.path])
task.project.logger.warn "${task.path} took ${ms}ms"
}

@Override
void buildFinished(BuildResult result) {
println "Task timings:"
for (timing in timings) {
if (timing[0] >= 50) {
printf "%7sms %s\n", timing
}
}
}
@Override
void buildStarted(Gradle gradle) {}

@Override
void projectsEvaluated(Gradle gradle) {}

@Override
void projectsLoaded(Gradle gradle) {}

@Override
void settingsEvaluated(Settings settings) {}
}

gradle.addListener new TimingsListener()

上面是对每个任务计时的一个例子,想要了解每个任务的作用,你可以修改上面的脚本,打印出每个任务的inputs和outputs。比如assembleDebug那么多依赖任务,每个都是干什么的,一会compile,一会generate,有什么区别?看到每个task的输入输出,就可以大体看出它的作用。如果对assemble的每个任务监听,你会发现改一行代码build的时间主要花费在了dex上,buck牛逼的地方就是对这个地方进行了优化,大大减少了增量编译运行的时间。

buildscript方法

Android项目中,根工程默认的build.gradle应该是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.2.3'
}
}

allprojects {
repositories {
jcenter()
}
}

一会一个jcenter()这是在干什么?buildscript方法的作用是配置脚本的依赖,而我们平常用的compile是配置project的依赖。repositories的意思就是需要包的时候到哥这里来找,然后你以为com.android.tools.build:gradle:1.2.3会从jcenter那里下载了是吧,图样图森破,不信加入下面这段脚本看看输出:

1
2
3
4
5
6
7
8
9
10
11
buildscript {
repositories {
jcenter()
}
repositories.each {
println it.getUrl()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.2.3'
}
}

结果是这样的:

1
file:/Applications/Android%20Studio.app/Contents/gradle/m2repository/ https://jcenter.bintray.com/

我靠,仓库竟然直接在Android Studio应用内部,所以说你去掉buildscript的jcenter()完全没有关系啊,下面还有更爽的,我们知道有依赖传递,上面classpath 中的gradle依赖gradle-core,gradle-core依赖lint,lint依赖lint-checks,lint-checks最后依赖到了asm,并且这个根目录中的依赖配置会传到所有工程的配置文件,所以如果你要引用asm相关的类,不用设置classpath,直接import就可以了。你怎么知道前面的依赖关系的?看上面m2repository目录中对应的pom文件就可以了。 为什么讲到ASM呢?ASM又是个比较刁的东西,可以直接用来操纵Java字节码,达到动态更改class文件的效果。可以用ASM面向切面编程,达到解耦效果。Android DEX自动拆包及动态加载简介中提到的class依赖分析和R常量替换的脚本都可以用ASM来搞

引入脚本

脚本写多了,都挤在一个build.gradle里也不好,人长大了总要自己出去住,那可以把部分脚本抽出去吗?当然可以,新建一个other.gradle把脚本抽离,然后在build.gradle中添加apply from ‘other.gradle’即可,抽出去以后你会发现本来可以直接import的asm包找不到了,怎么回事?根工程中配置的buildscript会传递到所有工程,但只会传到build.gradle脚本中,其他脚本可不管,所以你要在other.gradle中重新配置buildscript,并且other.gradle中的repositories不再包含m2repository目录,自己配置jcenter()又会导致依赖重新下载到~/.gradle/caches目录。如果不想额外下载,也可以在other.gradle中这么搞:

1
2
3
4
5
6
7
8
9
10
buildscript {
repositories {
maven {
url rootProject.buildscript.repositories[0].getUrl()
}
}
dependencies {
classpath 'com.android.tools.build:gradle:1.2.3'
}
}
获取AndroidManifest文件

ApplicationId versus PackageName提到,gradle中的applicationid用来区分应用,manifest中packageName用来指定R文件包名,并且各个productFlavor 的manifest中的packageName应该一致。applicationid只是gradle脚本中的定义,其实最后生成的apk中的manifest文件的packageName还是会被applicationid替换掉。

那获取R文件的包名怎么搞?要获取AndroidManifest中package属性,并且这个manifest要是起始的文件,因为最终文件中的package属性会被applicationid冲掉,由于各个manifest中的package属性一样,并且非主manifest可以没有package属性,所以只有获取主manifest的package属性才是最准确的。

def manifestFile = android.sourceSets.main.manifest.srcFile def packageName = new XmlParser().parse(manifestFile).attribute(‘package’)

无用资源
transitive = true

transitive dependencies 被称为依赖的依赖,称为“间接依赖”比较合适。

1
2
3
4
5
compile('com.meituan.android.terminus:library:6.6.1.16@aar'){
transitive = true
exclude module: 'hotel_model'
exclude module: 'base_model'
}

在后面加上@aar,意指你只是下载该aar包,而并不下载该aar包所依赖的其他库,那如果想在使用@aar的前提下还能下载其依赖库,则需要添加transitive=true的条件。 排除 transitive dependencies 通过configuration或者dependency可以除去 transitive dependencies:

build.gradle

1
2
3
4
5
6
7
8
9
10
configurations {
compile.exclude module: 'commons'
all*.exclude group: 'org.gradle.test.excludes', module: 'reports'
}

dependencies {
compile("org.gradle.test.excludes:api:1.0") {
exclude module: 'shared'
}
}

如果在configuration中定义一个exclude,那么所有依赖的transitive dependency (指定的)都会被去除。 定义exclude时候,或只指定group, 或只指定module名字,或二者都指定。

不是所有的transitive dependency 都可以被去除的,如runtime时候使用到的。一般来说,runtime时候用不到的,或者目标环境及平台已经包含该依赖的可以执行exclude去除。

那exclude选per-dependency还是per-configuration?,大多数情况我们都选用per-configuration,下面是一些使用exclude的典型场合:

  • 有licensing问题
  • 从远程仓库上无法获取到依赖
  • runtime时候用不到
  • 有版本冲突

可以给dependencies统一指定transitive为false,再次执行dependencies可以看到如下结果。

1
2
3
4
5
6
7
8
configurations.all {
transitive = false
}
dependencies {
androidTestCompile('com.android.support.test:runner:0.2')
androidTestCompile('com.android.support.test:rules:0.2')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.1')
}
exclude的疑问
1
exclude module: 'base_model'

和

1
exclude group:'com.name.group' module:'base_model'

的区别是? 经过测试,二者的作用是完全一样的。

force=true
1
2
3
compile('com.squareup.okhttp:okhttp-mt:2.5.0') {
force = true
}

如上,我们在依赖okhttp的时候很可能发生冲突,就比如依赖的依赖中也包含了okhttp,这种场合下,就会产生版本冲突的问题,加上force = true表明的意思就是即使在有依赖库版本冲突的情况下坚持使用被标注的这个依赖库版本。

gradle命令
  • gradlew projects:查看所有项目
  • gradlew tasks:查看任务信息
  • -b参数指定其他的构建文件
  • -p:参数指定要使用的构建文件的文件夹,例如我们将subdir中的构建文件重命名为build.gradle,然后运行gradle -q -p subdir hello
  • gradle -q projects 列出所有项目的信息(-q静默参数,功能是只显示任务输出,不显示其他构建过程的输出)
  • gradle -q tasks 列出所有任务
  • gradle help –task someTask:显示任务帮助
  • 使用-m参数可以以Dry Run的方式运行Gradle,在这种方式下不会执行任何任务,只会列出这些任务的执行顺序

在运行Gradle的时候我们不用完整输入任务名称,如果任务的前几个字母就可以区分任务,我们就可以只输入这几个字母。比如gradle d相当于gradle dist。另外Gradle还支持驼峰命名法的缩写。比如说我们可以运行gradle cT,相当于gradle compileTest。

引用
  • 建立企业内部maven服务器并使用Android Studio发布公共项目

anaconda环境搭建

发表于 2018-04-03 | 分类于 ml

anaconda指的是一个开源的Python发行版本,其包含了conda、Python等180多个科学包及其依赖项。因为包含了大量的科学包,比如ipython、ipython notebook、numpy等一些数据分析包,这样我们不必单独的安装各种工具包,简单有效!

官网下载地址为:https://www.anaconda.com/download/

安装anaconda

对于Mac、Linux系统,Anaconda安装好后,实际上就是在主目录下多了个文件夹(/anaconda)而已,Windows会写入注册表。安装时,安装程序会把bin目录加入PATH(Linux/Mac写入/.bashrc,Windows添加到系统变量PATH),这些操作也完全可以自己完成。以Linux/Mac为例,安装完成后设置PATH的操作是

1
2
3
4
# 将anaconda的bin目录加入PATH,根据版本不同,也可能是~/anaconda3/bin
echo 'export PATH="~/anaconda2/bin:$PATH"' >> ~/.bashrc
# 更新bashrc以立即生效
source ~/.bashrc

配置好PATH后,可以通过which conda或conda –version命令检查是否正确。假如安装的是Python 2.7对应的版本,运行python –version或python -V可以得到Python 2.7.12 :: Anaconda 4.1.1 (64-bit),也说明该发行版默认的环境是Python 2.7。

Conda的环境管理

Conda的环境管理功能允许我们同时安装若干不同版本的Python,并能自由切换。对于上述安装过程,假设我们采用的是Python 2.7对应的安装包,那么Python 2.7就是默认的环境(默认名字是root,注意这个root不是超级管理员的意思)。

假设我们需要安装Python 3.4,此时,我们需要做的操作如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 创建一个名为python34的环境,指定Python版本是3.4(不用管是3.4.x,conda会为我们自动寻找3.4.x中的最新版本)
conda create --name python34 python=3.4

# 安装好后,使用activate激活某个环境
activate python34 # for Windows
source activate python34 # for Linux & Mac
# 激活后,会发现terminal输入的地方多了python34的字样,实际上,此时系统做的事情就是把默认2.7环境从PATH中去除,再把3.4对应的命令加入PATH

# 此时,再次输入
python --version
# 可以得到`Python 3.4.5 :: Anaconda 4.1.1 (64-bit)`,即系统已经切换到了3.4的环境

# 如果想返回默认的python 2.7环境,运行
deactivate python34 # for Windows
source deactivate python34 # for Linux & Mac

# 删除一个已有的环境
conda remove --name python34 --all

用户安装的不同python环境都会被放在目录~/anaconda/envs下,可以在命令中运行conda info -e查看已安装的环境,当前被激活的环境会显示有一个星号或者括号。

说明:有些用户可能经常使用python 3.4环境,因此直接把~/anaconda/envs/python34下面的bin或者Scripts加入PATH,去除anaconda对应的那个bin目录。这个办法,怎么说呢,也是可以的,但总觉得不是那么elegant……

如果直接按上面说的这么改PATH,你会发现conda命令又找不到了(当然找不到啦,因为conda在~/anaconda/bin里呢),这时候怎么办呢?方法有二:1. 显式地给出conda的绝对地址 2. 在python34环境中也安装conda工具(推荐)。

Conda的包管理

Conda的包管理就比较好理解了,这部分功能与pip类似。

例如,如果需要安装scipy:

1
2
3
4
5
6
7
# 安装scipy
conda install scipy
# conda会从从远程搜索scipy的相关信息和依赖项目,对于python 3.4,conda会同时安装numpy和mkl(运算加速的库)

# 查看已经安装的packages
conda list
# 最新版的conda是从site-packages文件夹中搜索已经安装的包,不依赖于pip,因此可以显示出通过各种方式安装的包

conda的一些常用操作如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
conda的一些常用操作如下:

# 查看当前环境下已安装的包
conda list

# 查看某个指定环境的已安装包
conda list -n python34

# 查找package信息
conda search numpy

# 安装package
conda install -n python34 numpy
# 如果不用-n指定环境名称,则被安装在当前活跃环境
# 也可以通过-c指定通过某个channel安装

# 更新package
conda update -n python34 numpy

# 删除package
conda remove -n python34 numpy

前面已经提到,conda将conda、python等都视为package,因此,完全可以使用conda来管理conda和python的版本,例如

1
2
3
4
5
6
7
8
9
# 更新conda,保持conda最新
conda update conda

# 更新anaconda
conda update anaconda

# 更新python
conda update python
# 假设当前环境是python 3.4, conda会将python升级为3.4.x系列的当前最新版本

补充:如果创建新的python环境,比如3.4,运行conda create -n python34 python=3.4之后,conda仅安装python 3.4相关的必须项,如python, pip等,如果希望该环境像默认环境那样,安装anaconda集合包,只需要:

1
2
3
4
5
6
# 在当前环境下安装anaconda包集合
conda install anaconda

# 结合创建环境的命令,以上操作可以合并为
conda create -n python34 python=3.4 anaconda
# 也可以不用全部安装,根据需求安装自己需要的package即可
通过pip将packages安装到Conda环境中

发行版Anaconda附带安装了200多个Python软件包,还可以使用conda install 命令快速轻松地安装许多软件包。

除了安装和管理软件包的实用程序外,conda还拥有创建虚拟环境的能力,这些虚拟环境是在没有任何Python包预先加载的情况下创建的。 但是不是所有的软件包都可以通过 conda 安装,如果你想要一个不可用的软件,那么你将不得不使用备用软件包管理器pip。Anaconda的软件包管理器conda和pip如何相互交互? 目前有两种方法:

一、以下是如何在conda虚拟环境中使用pip安装软件包。首先要建立起来:
  1. 使用conda create - name virtual_env_name 创建您的虚拟环境,用虚拟环境的 名称 替换virtual_env_name
  2. 使用source activate virtual_env_name切换到您的虚拟环境 ,再次用您的虚拟环境的名称替换virtual_env_name
  3. 运行conda install pip ,它会将pip安装到您的虚拟环境目录中
  4. 后续直接使用以下两步即可:1)source activate virtual_env_name 2)pip install ‘package_name’
二、第二种方法不单独创建虚拟环境,直接用Anaconda本身的虚拟环境。个人还是建议第一种。
  1. 运行conda install pip ,它会将pip安装到您的Anaconda虚拟环境目录中。
  2. 你需要找到你的Anaconda bin目录运行pip,如://anaconda/bin/pip install package_name将软件包安装到您的虚拟环境中 。

设置国内镜像

如果需要安装很多packages,你会发现conda下载的速度经常很慢,因为Anaconda.org的服务器在国外。所幸的是,清华TUNA镜像源有Anaconda仓库的镜像,我们将其加入conda的配置即可:

1
2
3
4
5
6
# 添加Anaconda的TUNA镜像
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
# TUNA的help中镜像地址加有引号,需要去掉

# 设置搜索时显示通道地址
conda config --set show_channel_urls yes

执行完上述命令后,会生成~/.condarc(Linux/Mac)或C:\Users\USER_NAME\.condarc文件,记录着我们对conda的配置,直接手动创建、编辑该文件是相同的效果。

为vscode配置集成环境

VS Code下载地址为: https://code.visualstudio.com/Download 安装完anaconda会自动提示安装VS Code,如果已安装就不会安装,只会安装插件Anaconda Extension.

添加Python编译配置

首选项->设置,打开一个setting.json

1
2
3
4
5
6
7
//配置python的路径
"python.pythonPath": "D:/Program Files/Anaconda3/python",
"editor.fontFamily": "Consolas",
//忽略pylint检查代码时,出现无谓的波浪线的问题
"python.linting.pylintArgs": [
"--disable=W,C"
]
Python脚本编译测试

新建test.py,代码如下:

1
2
3
4
5
6
7
8
9
10
11
# plot a sine wave from 0 to 4pi  
from pylab import *
x_values = arange(0.0, math.pi * 4, 0.01)
y_values = sin(x_values)
plot(x_values, y_values, linewidth=1.0)
xlabel('x')
ylabel('sin(x)')
title('Simple plot')
grid(True)
savefig("sin.png")
show()

我们可以看到,代码中调用了matplotlib数据包,并且代码编译通过,显示出所打印的正弦波图像。

多媒体技术(四)之音频,视频信号及数字化

发表于 2018-03-04 | 分类于 media

带宽

宽应用的领域非常多,可以用来标识信号传输的数据传输能力、标识单位时间内通过链路的数据量、标识显示器的显示能力。

  1. 在模拟信号系统又叫频宽,是指在固定的时间可传输的资料数量,亦即在传输管道中可以传递数据的能力。通常以每秒传送周期或赫兹(Hz)来表示。
  2. 在数字设备中,带宽指单位时间能通过链路的数据量。通常以bps来表示,即每秒可传输之位数。
  3. 信号的带宽是指该信号所包含的各种不同频率成分所占据的频率范围。频宽对基本输出入系统 (BIOS ) 设备尤其重要,如快速磁盘驱动器会受低频宽的总线所阻碍。

带宽:带宽是反映信号频率通过能力,带宽越大,对信号中的各种频率成分(特别是高频成分)能准确有效地放大与显示,也就较为准确,如果带宽不够,那就会损失很多高频成分,信号自然就显示不准确了,出现较大误差。 在一秒的时间内最大最多能通过的信号,所以带宽要大于等于最高频率fmax. 采样率: 而采样率是将模拟量转换为数字量时对信号转换的频率(即每秒采集次数),这个频率越高,单位时间内对信号的采集就越多,信号中的信息就保留越多,丢失信息就少,转换出的数字量就能准确反映信号的数值.

香农采样定理:采样定理说明采样频率与信号频谱之间的关系,是连续信号离散化的基本依据,在进行模拟/数字信号的转换过程中,当采样频率fs.max大于信号中最高频率fmax的2倍时(fs.max>2fmax),采样之后的数字信号完整地保留了原始信号中的信息,一般实际应用中保证采样频率为信号最高频率的2.56~4倍;采样定理又称奈奎斯特定理。 在工程中为了方便计算机的计算,一般去fs=2.56fmax. 一个正弦波形至少可用2个点来描述. 对连续信号进行等间隔采样时,如果采样频率不满足采样定理,采样后信号的频率就会发生混叠,即高于奈奎斯特频率的频率成分将被重构成低于奈奎斯特频率的信号,如果发生混叠,就无法准确的重建出原始声音的音频信号。

如何查看最高频率(或者是感兴趣的)呢? 用AU打开一段音频,在波形下边打开频域图,看看你感兴趣的谐波或者共振峰的频域的什么范围,找出最大值,即可确定为带宽,那么 采样率 = 带宽*2.5

频段,是一个有关通讯和声音理学方面的词语,通讯方面的频段意思是指一定的无线电波的频率范围;声音和音乐中的频段是指声音频率而言,人耳对声音频率的感觉是从最低的20Hz到最高的20KHz,而人的语音频率范围则集中在80Hz~12kHz之间,不同频段的声音对人的感受是不同的. 带宽(band width)又叫频宽,是指在固定的的时间可传输的资料数量,亦即在传输管道中可以传递数据的能力.在数字设备中,频宽通常以bps表示,即每秒可传输之位数.在模拟设备中,频宽通常以每秒传送周期或赫兹 (Hz)来表示. 速率:是物体运动的快慢,即速率是速度的大小或等价于路程的变化率.在初中物理中被称为速度,但应与高中物理中的速度加以区别.在网络应用中应该是传输速度之比.

多媒体技术(1.1)之图像分辨率

发表于 2018-03-04 | 分类于 media

「分辨率」这个概念还有「解析度」等说法,所以能从字面上看出来,它描述的其实就是图像包含多少细节、有多「清晰」。但具体到怎么用数字来描述一个图像有多少细节,就有很多个描述的角度,于是「分辨率」有很多种意思。

  • 相机的分辨率,往往指的是它的「像素规模」,即它能拍出含有多少个像素的照片。我们可以简单地说「10 M(一千万像素,有时也写成 10 MP)」,也可以写成「4000 × 2672 像素」。对相机来说,把像素和图片物理尺寸联系起来是没有什么意义的,因为相机总是在缩放物体的图像。
  • 扫描仪和打印机的分辨率,往往是它们能在单位物理面积内扫描/打印多少个微小的点(像素或墨点),单位一般分别是 PPI(像素/每英寸)和 DPI(点/英寸)──因为把它们的像素/点和物理尺寸联系起来是有意义的。为什么不写它们能扫描/打印包含多少像素/点的图片呢?因为它们扫描/打印的图片尺寸不定呀!所以我们只能以单位面积来描述。
  • 显示器 能显示包含多少像素的图像的能力是固定的,所以我们可以像描述相机一样说它「1440 × 900 像素」。而它的物理尺寸是有意义的,所以也可以像描述扫描仪一样说它有多少 PPI,此时我们经常用「像素密度」来特指这个 PPI 参数。
  • 为什么上面说了这么多,却一直不说图片?因为图片是穿梭在上面说的这些设备之间的东西,它的「分辨率」概念和相机、扫描仪、打印机、显示器都有关。图片的分辨率一般有两种,一种是像相机一样描述总共有多少个像素(如「10 M」)或写成像素数量的乘法(如「4000 × 2672 像素」),另一种是像打印机一样使用 DPI 来确定图片的每一个像素(视作一个「点」)和实际的一个长度单位(英寸)之间的大小比例(比如「300 DPI」)。

    基本概念

    像素

image 组成这张图的单位是一个格子一个格子的颜色小方块组成的,这种小方块就叫做像素。像素就是图像显示的基本元素。

通过一点的排列,最终就会形式我们看到的图片,这类图片我们把它叫做“栅格图”、“点阵图”,所以你现在懂PS里图片拖进去后为什么要右键图层栅格化对象吧。

像素都是正方形? 不一定,我们看一张图: image

根据显示媒介的不同可能会对像素值进行压缩或者扩大。大家在PS中新建画布的时候最下面有一个选择: image

单指是没大小的和面积概念的,不能说,一个像素固定是多少平方微米吧。只有在单位面积分辨率里,像素有了大小。如1分辨率/英寸,就是这个像素是1英寸大。72分辨率就是1英寸长,宽段里都有72个像素。。 图片是像素为最基本单位,给像素赋予不同明暗的颜色,组成位图图片。。

分辨率

是图像清晰度,像素密度排列,像素在单位面积里排列越密,反映色阶过渡是越细,当然就越清晰,画面细腻。。如同面积里,10个像素来反映红黄过渡和30个像素来反映,自然30个像素反映色阶细腻,多20个来过渡。。 放大像素就是插值,如原来1英寸里10像素,放大到30个,那新增加的20个像素哪里来,是软件根据像素周围取样来加出来,因为加出来的像素颜色不能准确到位,就会不清晰,模糊了。。 如分辨率减小,尺寸不变,像素会被拿掉,那就是像素连续色调产生断层了,模糊自然产生。。 还有个概念,72分辨率是显示器的物理分辨率,图片像素尺寸和显示器尺寸同比显示,大了,图片会超出屏幕来显示,所以有显示大小和实际大小。。

分辨率其实包含两个概念的:

  1. 图像分辨率:就是说该图像的宽高上的像素点数。这个值在一开始图案生成的时候就已经确定下来。
  2. 显示(单位)分辨率:在显示媒介上在单位长度内显示多少像素(相对值,这个和你的显示终端的分辨率有关)

在单位上,分辨率是以DPI和PPI来作为单位的

  • 像素/英寸 Dots Per Inch
  • 像素/厘米 Pixel Per Inch

图像清晰有两个因素决定:

  • 显示媒介的分辨率
  • 图片的分辨率
  • 查看的空间距离

根据行业里的规则,一般来说,打印的出图DPI一般300即可满足需求。还记得乔布斯给苹果定义的视网膜屏幕吗?它将960×640的像素压缩到一个3.5英寸的显示屏内。也就是说,该屏幕的像素密度达到326像素/英寸(ppi),称之为“视网膜屏幕”。但是,如果你隔老远看手机屏幕,基本上你就告别视网膜屏幕了.一般来说,电子设备在0.3-0.4米的范围内使用300dpi即可很清晰.所以你可以推,你家里的电视如果观赏距离是3-4m那么像素值30dpi即可。

总结

图片大小的4个容易混淆的概念

  • 像素数目(Pixels):宽1024px,高768px

  • 实际尺寸(Print Size):厘米,英尺Inch

  • 分辨率(Resolution):DPI(dots per inch)

  • 占用磁盘空间:几兆M,几k

  • 像素数目(垂直或水平)=分辨率*实际尺寸

  • Pixels = Resolution(DPI)x Print size(in inches)

  • 图片质量取决于:像素数目;颜色种类(位深度)

  • 平时所说的屏幕分辨率,相机分辨率,其实指的是像素数目

多媒体技术(1.1)之图像中频率的概念

发表于 2018-02-27 | 分类于 media

一、图像高频信号和低频信号的理解 1.1 图像中的低频信号和高频信号也叫做低频分量和高频分量。简单一点说,图像中的高频分量,指的是图像强度(亮度/灰度)变化剧烈的地方,也就是我们常说的边缘(轮廓);图像中的低频分量,指的是图像强度(亮度/灰度)变换平缓的地方,也就是大片色块的地方。人眼对图像中的高频信号更为敏感。 图像的高低频是对图像各个位置之间强度变化的一种度量方法。低频分量:主要对整副图像的强度的综合度量. 高频分量:主要是对图像边缘和轮廓的度量。如果一副图像的各个位置的强度大小相等,则图像只存在低频分量,从图像的频谱图上看,只有一个主峰,且位于频率为零的位置。 如果一副图像的各个位置的强度变化剧烈,则图像不仅存在低频分量,同时也存在多种高频分量,从图像的频谱上看,不仅有一个主峰,同时也存在多个旁峰。 1.2直观认识 假设在正弦波中有一个毛刺,并且正弦波的变化非常的缓慢,频率较低,在正弦波上有一个毛刺,这个毛刺在短时间内就完成了一个变化周期,频率较高。所以我们就把这里的正弦波称为低频信号,而毛刺就称为高频信号。如果要对这个曲线平滑滤波的话,效果就是把毛刺滤掉,也就是说,平滑滤波的操作会将高频信号去除而低频信号保留,也就是我们常说的低通滤波器了。 最简单的低通滤波器的实现就是中值或者均值滤波器。 由以上的认识推广到二维图像上,也就不难知道为什么会将图像上变化剧烈的地方叫做高频信号,而变化平缓的地方叫做低频信号了。 二、图像频率的理解 1不同频率信息在图像结构中有不同的作用。图像的主要成分是低频信息,它形成了图像的基本灰度等级,对图像结构的决定作用较小;中频信息决定了图像的基本结构,形成了图像的主要边缘结构;高频信息形成了图像的边缘和细节,是在中频信息上对图像内容的进一步强化。 2图像的频率是表征图像中灰度变化剧烈程度的指标,是灰度在平面空间上的梯度。如:大面积的沙漠在图像中是一片灰度变化缓慢的区域,对应的频率值很低;而对于地表属性变换剧烈的边缘区域在图像中是一片灰度变化剧烈的区域,对应的频率值较高。 3对图像而言,图像的边缘部分是突变部分,变化较快,因此反应在频域上是高频分量;图像的噪声大部分情况下是高频部分;图像平缓变化部分则为低频分量。也就是说,傅立叶变换提供另外一个角度来观察图像,可以将图像从灰度分布转化到频率分布上来观察图像的特征。 4图像进行二维傅立叶变换得到频谱图,就是图像梯度的分布图,当然频谱图上的各点与图像上各点并不存在一一对应的关系,即使在不移频的情况下也是没有。傅立叶频谱图上我们看到的明暗不一的亮点,实际是上图像上某一点与邻域点差异的强弱,即梯度的大小,也即该点的频率的大小(可以这么理解,图像中的低频部分指低梯度的点,高频部分相反)。 5图像的频率,不是图像上某一个点的频率,它反映了反应了图像像素变化的快慢,也就是说,在某一区域变化的非常大非常的快,那这一区域就携带有一定的高频的信息。图像的高频信息越多,图像的细节特征也就越多。

图像的频率:灰度值变化剧烈程度的指标,是灰度在平面空间上的梯度。 (1)什么是低频? 低频就是颜色缓慢地变化,也就是灰度缓慢地变化,就代表着那是连续渐变的一块区域,这部分就是低频. 对于一幅图像来说,除去高频的就是低频了,也就是边缘以内的内容为低频,而边缘内的内容就是图像的大部分信息,即图像的大致概貌和轮廓,是图像的近似信息。

(2)什么是高频? 反过来, 高频就是频率变化快.图像中什么时候灰度变化快?就是相邻区域之间灰度相差很大,这就是变化得快.图像中,一个影像与背景的边缘部位,通常会有明显的差别,也就是说变化那条边线那里,灰度变化很快,也即是变化频率高的部位.因此,图像边缘的灰度值变化快,就对应着频率高,即高频显示图像边缘。图像的细节处也是属于灰度值急剧变化的区域,正是因为灰度值的急剧变化,才会出现细节。 另外噪声(即噪点)也是这样,在一个像素所在的位置,之所以是噪点,就是因为它与正常的点颜色不一样了,也就是说该像素点灰度值明显不一样了,,也就是灰度有快速地变化了,所以是高频部分,因此有噪声在高频这么一说。

其实归根到底,是因为我们人眼识别物体就是这样的.假如你穿一个红衣服在红色背景布前拍照,你能很好地识别么?不能,因为衣服与背景融为一体了,没有变化,所以看不出来,除非有灯光从某解度照在人物身上,这样边缘处会出现高亮和阴影,这样我们就能看到一些轮廓线,这些线就是颜色(即灰度)很不一样的地方.

首先说说图像频率的物理意义。图像可以看做是一个定义为二维平面上的信号,该信号的幅值对应于像素的灰度(对于彩色图像则是RGB三个分量),如果我们仅仅考虑图像上某一行像素,则可以将之视为一个定义在一维空间上信号,这个信号在形式上与传统的信号处理领域的时变信号是相似的。不过是一个是定义在空间域上的,而另一个是定义在时间域上的。所以图像的频率又称为空间频率,它反映了图像的像素灰度在空间中变化的情况。例如,一面墙壁的图像,由于灰度值分布平坦,其低频成分就较强,而高频成分较弱;而对于国际象棋棋盘或者沟壑纵横的卫星图片这类具有快速空间变化的图像来说,其高频成分会相对较强,低频则较弱(注意,是相对而言)。再来谈一谈如何定量的测量图像的空间频率,最为常用的方法就是二维傅里叶变换。图像经过二维傅里叶变换后会形成与图像等大的复数矩阵,取其幅值形成幅度谱,取其相位形成相位谱。图像的频率能量分布主要体现在幅度谱中。通常习惯将低频成分放在幅度谱的中央,而将高频成分放在幅度谱边缘。大多数自然图像的幅度谱在统计上呈现1/f^2分布,也就是频率成分的能量与频率的平方成反比。所以从绝对数值上看,低频能量通常是要高于高频能量的,这一规则也称为power law。power law并非是上帝的无心之作,事实上power law的出现时源于自然图像的尺度不变性(scale invariance)。这一点在很多文献中被解释为从不同的距离观察同样的自然场景,获得的图像的幅度谱是基本相同的。相关内容可以搜索关键字power law & natural image statistics。除了傅里叶变换外,正弦变换、余弦变换、Gabor变换、小波变换、WH变换也可以用来对图像频率分布进行定量测量。目前小波变换是研究的热点,因为小波变换不但能够反映频率能量的分布,同时还保留了图像特征的空间分布特性。

在 最近十年中,视频工程师发现人眼对色度的敏感程度要低于对亮度的敏感程度。在生理学中,有一条规律,那就是人类视网膜上的视网膜杆细胞要多于视网膜锥细 胞,说得通俗一些,视网膜杆细胞的作用就是识别亮度,而视网膜锥细胞的作用就是识别色度。所以,你的眼睛对于亮和暗的分辨要比对颜色的分辨精细一些。正是 因为这个,在我们的视频存储中,没有必要存储全部颜色信号。既然眼睛看不见,那为什么要浪费存储空间(或者说是金钱)来存储它们呢?

vr播放器

发表于 2018-02-11 | 分类于 media

VR播放器的简单原理

一个VR视频如果不使用特殊的播放器,那么播放出来的效果看上去是一个拉伸的长条形图片拼成的视频。

之所以Vr视频能让人有身处其中的感觉,是因为观看时人的视角处于VR视频空间中,而不是看到一个二维平面,因此就需要将本身的全景二维图,投影到一个立体的空间——立方体or球形。

简单球面纹理映射讲解

实现球面纹理映射有两种方法,一种是使用顶点的法向量来生成纹理坐标,另一个是使用顶点的位置向量来生成纹理坐标。

想象一个球体,球面上每一个点的法向量,可以是从球心起到该点的线段距离。球上每一点都可以视作一个无限小的平面。

Ps:法向量——垂直于平面的向量,叫做该平面的法向量

问题的本质是根据球面上每个点的法向量坐标生成对应的纹理坐标,请看下图,下图中外部的方框表示二维纹理坐标,其范围是(u,v)min = (0,0), (u,v)max = (1,1),中间的圆形表示球面法向量坐标,其x,y分量的范围是(x,y)min = (-1,-1), (x,y)max = (1,1)。

所以问题的本质变成了两组坐标的映射,也即将区间(x,y)min - (x,y)max映射到区间(u,v)min - (u,v)max。这里我们使用反正弦函数y = acrsin(x)来实现。先看一下它的函数图象。

由这个图象知,它的定义域x = (-1,1),值域是y = (-pi / 2, pi / 2)。我们稍作变型,得到下面两个公式。正好完成了由(-1, 1)到(0, 1)的映射。这里tu表示纹理的x坐标,tv表示纹理的y坐标,Nx表示顶点法向量的x轴分量,Ny表示顶点法向量的y轴分量。

1
2
tu = arcsin(Nx) / PI + 0.5
tv = arcsin(Ny) / PI + 0.5

ts格式解析

发表于 2018-02-11 | 分类于 音视频封装

ts是日本高清摄像机拍摄下进行的封装格式,全称为MPEG2-TS。ts即”Transport Stream”的缩写。MPEG2-TS格式的特点就是要求从视频流的任一片段开始都是可以独立解码的。MPEG2-TS主要应用于实时传送的节目,比如实时广播的电视节目。

发展简要

随着从HDTV录制的高清节目在网上的流传,发烧友们现在对TS这个名词大概已经不陌生了,但随之而来就是如何播放、如何添加字幕等等的一系列问题,本文将重点介绍一下这方面的应用操作。 先来简要介绍一下什么是MPEG2-TS吧。MPEG2格式大家都通过对DVD的接触而多多少少了解了一些,DVD节目中的MPEG2格式,确切地说是MPEG2-PS,全称是Program Stream,而TS的全称则是Transport Stream。MPEG2-PS主要应用于存储的具有固定时长的节目,如DVD电影,而MPEG-TS则主要应用于实时传送的节目,比如实时广播的电视节目。这两种格式的主要区别是什么呢?简单地打个比喻说,你将DVD上的VOB文件的前面一截cut掉(或者干脆就是数据损坏),那么就会导致整个文件无法解码了,而电视节目是你任何时候打开电视机都能解码(收看)的,所以,MPEG2-TS格式的特点就是要求从视频流的任一片段开始都是可以独立解码的。

学习多媒体容器格式的目的

主要是为了回答以下问题:

  • 该容器中数据是如何组织的?
  • 该容器包含哪些编码格式的数据?这些数据是如何存储的?
  • 该容器包含哪些元数据信息?包含哪些节目信息?
  • 对于支持多节目的容器格式,如何找到对应的音频流、视频流、字幕流?
  • 如何确定该容器的节目播放时长?
  • 如何从该容器中提取音频、视频、字幕数据,并交给解码器解码,有时间戳否?
  • 该容器是否支持seek?有哪些辅助信息?
  • 是否支持直接流化?
  • 哪里可以找到该容器格式最标准的文档资料?
  • 有哪些可用的工具,方便分析容器格式异常或者错误?

TS流生成和解析的过程

TS流的形成过程:

  1. 将原始音视频数据压缩之后,压缩结果组成一个基本码流(ES)。
  2. 对ES(基本码流)进行打包形成PES。
  3. 在PES包中加入时间戳信息(PTS/DTS)。
  4. 将PES包内容分配到一系列固定长度的传输包(TS Packet)中。
  5. 在传输包中加入定时信息(PCR)。
  6. 在传输包中加入节目专用信息(PSI) 。
  7. 连续输出传输包形成具有恒定比特率的MPEG-TS流。

TS流的解析过程,可以说是生成的逆过程:

  1. 从复用的MPEG-TS流中解析出TS包;
  2. 从TS包中获取PAT及对应的PMT(PSI中的表格);
  3. 从而获取特定节目的音视频PID;
  4. 通过PID筛选出特定音视频相关的TS包,并解析出PES;
  5. 从PES中读取到PTS/DTS,并从PES中解析出基本码流ES;
  6. 将ES交给解码器,获得压缩前的原始音视频数据。

TS码流整体结构

MPEG-2中规定TS传输包的长度为188 字节,包头为4个字节,负载为184个字节。但通信媒介会为包添加错误校验字节,从而有了不同于188字节的包长。例如:

DVB 规定中,使用204字节作为包长:

  1. 通过调制器时,在每个传输包后增加了16 字节的里德所罗门前向纠错码,因而形成了204字节的数据包。调制后总存在204 字节的数据包。
  2. 调制之前存复用器插入RS码或虚构的RS码。

ATSC规定中,使用208字节作为包长:添加20 字节的 RS(Reed-Solomon)前向纠错码。与DVB不同,ATSC规定RS码只能出现在调制的TS流中。

所有的TS包都分为包头和净荷部分。TS包中可以填入很多东西(填入的东西都是填入到净荷部分),有:视频、音频、数据(包括PSI、SI以及其它任何形式的数据)。 image

1、TS包包头

TS包的包头提供关于传输方面的信息:同步、有无差错、有无加扰、PCR(节目参考时钟)等标志。TS包的包头长度不固定,前32比特(4个字节)固定,后面可能跟有自适应字段(适配域)。32个比特(4个字节)是最小包头。

  • sync_byte (同步字节):固定为0100 0111 (0x47);该字节由解码器识别,使包头和有效负载可相互分离。
  • transport_error_indicator(传输错误指示):‘1’表示在相关的传输包中至少有一个不可纠正的错误位。当被置1后,在错误被纠正之前不能重置为0。
  • payload_unit_start_indicator(开始指示):为1时,在前4个字节之后会有一个调整字节,其的数值为后面调整字段的长度length。因此有效载荷开始的位置应再偏移1+[length]个字节。
  • transport_priority(传输优先级):‘1’表明优先级比其他具有相同PID 但此位没有被置‘1’的分组高。
  • PID:指示存储与分组有效负载中数据的类型。PID 值 0x0000—0x000F 保留。其中0x0000为PAT保留;0x0001为CAT保留;0x1fff为分组保留,即空包。
  • transport_scrambling_control(加扰控制):表示TS流分组有效负载的加密模式。空包为‘00’,如果传输包包头中包括调整字段,不应被加密。
  • adaptation_field_control(适配域控制):表示包头是否有调整字段或有效负载。‘00’为ISO/IEC未来使用保留;‘01’仅含有效载荷,无调整字段;‘10’ 无有效载荷,仅含调整字段;‘11’ 调整字段后为有效载荷,调整字段中的前一个字节表示调整字段的长度length,有效载荷开始的位置应再偏移[length]个字节。空包应为‘10’。
  • continuity_counter(连续性计数器):随着每一个具有相同PID的TS流分组而增加,当它达到最大值后又回复到0。范围为0~15。
  • adaptation_field (自适应字段 ):根据自适应控制字段填充负载。

image

2、节目专用信息PSI。

然,TS包也可以是空包。空包用来填充TS流,可能在重新进行多路复用时被插入或删除。

在系统复用时,视频、音频的ES流需进行打包形成视频、音频的 PES流,辅助数据(如图文电视信息)不需要打成PES包。PES包非定长,音频的PES包小于等于64K,视频的一般为一帧一个PES包。一帧图象的PES包通常要由许多个TS包来传输。MPEG-2中规定,一个PES包必须由整数个TS包来传输。如果承载一个PES包的最后一个TS包没能装满,则用填充字节来填满;当下一个新的PES包形成时,需用新的TS包来开始传输。

节目专用信息PSI(Program Specific Information)

管理各种类型的TS数据包,需要有些特殊的TS包来确立各个TS数据包之间的关系。这些特殊的TS包里所包含的信息就是节目专用信息。在不同的标准中它有不同的名字:

  • MPEG-2中称为PSI;
  • DVB标准根据实际需要,对PSI扩展,称为SI信息;
  • ATSC标准中为PSIP信息

MPEG-2中,规定的对PSI信息的描述方法有以下几种:

1、表Table: 节目信息的结构性的描述;
  • 节目关联表Program Association Table (PAT) 0x0000
  • 节目映射表Program Map Tables (PMT) PAT指定
  • 条件接收表Conditional Access Table (CAT) 0x0001
  • 网络信息表Network Information Table(NIT) 0x0010
  • 传送流描述表Transport Stream Description Table (TSDT)
    2、节Section: 将表格的内容映射到TS流中;
    专用段 Private_ section
3、描述符Descriptor:提供有关节目构成(视频流、音频流、语言、层次、系统时钟和码率等多方面)的信息;

ITU-T Rec.H.222.0|ISO /IEC 13818-1 中定义的 PSI表可被分成一段或多段置于传输流分组中。一段就是一个语法结构,用来将 ITU-T Rec.H.222.0|ISO /IEC 13818-1 中定义的 PSI表映射到传输流分组中。

PAT表

TS流中包含一个或者多个PAT表。PAT表由PID为0x0000的TS包传送,其作用是为复用的每一路传送流提供出所包含的节目和节目编号,以及对应节目的PMT的位置即PMT的TS包的PID值,同时还提供NIT的位置,即NIT的TS包的PID的值。

  • table_id:固定为0x00,标志该表是PAT表。
  • section_syntax_indicator:段语法标志位,固定为1。
  • section_length:表示这个字节后面有用的字节数,包括CRC32。节目套数:(section length-9)/4
  • transport_stream_id:16位字段,表示该TS流的ID,区别于同一个网络中其它多路复用流。
  • version_number:表示PAT的版本号。
  • current_next_indicator:表示发送的PAT表是当前有效还是下一个PAT有效。
  • section_number:表示分段的号码。PAT可能分为多段传输,第一段为0,以后每个分段加1,最多可能有256个分段。
  • last_section_number:表示PAT最后一个分段的号码。
  • Program number:节目号
  • network_PID:网络信息表(NIT)的PID,节目号为0时对应ID为network_PID。
  • Program map PID:节目映射表(PMT)的PID号,节目号为大于等于1时,对应的ID为program_map_PID。一个PAT中可以有多个program_map_PID。
  • CRC_32:32位字段,CRC32校验码Cyclic RedundancyCheck。
    PMT表

PMT在传送流中用于指示组成某一套节目的视频、音频和数据在传送流中的位置,即对应的TS包的PID值,以及每路节目的节目时钟参考(PCR)字段的位置。

  • Table id :固定为0x02,标志该表是PMT 表。
  • Section syntax indicator:对于PMT表,设置为1 。
  • Section length:表示这个字节后面有用的字节数,包括CRC32 。
  • Program number:它指出该节目对应于可应用的Program map PID 。
  • Version number:指出PMT 的版本号。
  • Current next indicator:当该位置’1’时,当前传送的Program map section可用;当该位置’0’时,指示当前传送的Program map section不可用,下一个TS流的Programmap section 有效。
  • Section number:总是置为0x00(因为PMT表里表示一个service的信息,一个section 的长度足够)。
  • Last section number:该域的值总是0x00 。
  • PCR PID:节目中包含有效PCR字段的传送流中PID 。
  • Program info length:12bit域,前两位为00。该域指出跟随其后对节目信息的描述的byte 数。
  • Stream type:8bit域,指示特定PID的节目元素包的类型。该处PID由elementary PID 指定。

HLS

HTTP Live Streaming(缩写是HLS)是一个由苹果公司提出的基于HTTP的流媒体网络传输协议。是苹果公司QuickTime X和iPhone软件系统的一部分。它的工作原理是把整个流分成一个个小的基于HTTP的文件来下载,每次只下载一些。当媒体流正在播放时,客户端可以选择从许多不同的备用源中以不同的速率下载同样的资源,允许流媒体会话适应不同的数据速率。在开始一个流媒体会话时,客户端会下载一个包含元数据的extended M3U (m3u8)playlist文件,用于寻找可用的媒体流。 HLS只请求基本的HTTP报文,与实时传输协议(RTP)不同,HLS可以穿过任何允许HTTP数据通过的防火墙或者代理服务器。它也很容易使用内容分发网络来传输媒体流。 苹果公司把HLS协议作为一个互联网草案(逐步提交),在第一阶段中已作为一个非正式的标准提交到IETF。但是,即使苹果偶尔地提交一些小的更新,IETF却没有关于制定此标准的有关进一步的动作。

HLS协议规定:

  • 视频的封装格式是TS。
  • 视频的编码格式为H264,音频编码格式为MP3、AAC或者AC-3。
  • 除了TS视频文件本身,还定义了用来控制播放的m3u8文件(文本文件)。

为什么苹果要提出HLS这个协议,其实他的主要是为了解决RTMP协议存在的一些问题。比如RTMP协议不使用标准的HTTP接口传输数据,所以在一些特殊的网络环境下可能被防火墙屏蔽掉。但是HLS由于使用的HTTP协议传输数据,不会遇到被防火墙屏蔽的情况(该不会有防火墙连80接口都不放过吧)。

另外于负载,RTMP是一种有状态协议,很难对视频服务器进行平滑扩展,因为需要为每一个播放视频流的客户端维护状态。而HLS基于无状态协议(HTTP),客户端只是按照顺序使用下载存储在服务器的普通TS文件,做负责均衡如同普通的HTTP文件服务器的负载均衡一样简单。

另外HLS协议本身实现了码率自适应,不同带宽的设备可以自动切换到最适合自己码率的视频播放。其实HLS最大的优势就是他的亲爹是苹果。苹果在自家的iOS设备上只提供对HLS的原生支持,并且放弃了flash。Android也迫于平果的“淫威”原生支持了HLS。这样一来flv,rtmp这些Adobe的视频方案要想在移动设备上播放需要额外下点功夫。当然flash对移动设备造成很大的性能压力确实也是自身的问题。

但HLS也有一些无法跨越的坑,比如采用HLS协议直播的视频延迟时间无法下到10秒以下,而RTMP协议的延迟最低可以到3、4秒左右。所以说对直播延迟比较敏感的服务请慎用HLS。

播放模式

  • 点播VOD的特点就是当前时间点可以获取到所有index文件和ts文件,二级index文件中记录了所有ts文件的地址。这种模式允许客户端访问全部内容。上面的例子中就是一个点播模式下的m3u8的结构。
  • Live 模式就是实时生成M3u8和ts文件。它的索引文件一直处于动态变化的,播放的时候需要不断下载二级index文件,以获得最新生成的ts文件播放视频。如果一个二级index文件的末尾没有#EXT-X-ENDLIST标志,说明它是一个Live视频流。

    TS码流分析 多媒体文件格式之TS ISO/IEC 13818-1:2015

MPEG

发表于 2018-02-08 | 分类于 media

MPEG

MPEG(Moving Picture Experts Group,动态图像专家组)是ISO(International Standardization Organization,国际标准化组织)与IEC(International Electrotechnical Commission,国际电工委员会)于1988年成立的专门针对运动图像和语音压缩制定国际标准的组织。

MPEG标准主要有以下五个,MPEG-1、MPEG-2、MPEG-4、MPEG-7及MPEG-21等。该专家组建于1988年,专门负责为CD建立视频和音频标准,而成员都是为视频、音频及系统领域的技术专家。及后,他们成功将声音和影像的记录脱离了传统的模拟方式,建立了ISO/IEC11172压缩编码标准,并制定出MPEG-格式,令视听传播方面进入了数码化时代。因此,大家现时泛指的MPEG-X版本,就是由ISO(International Organization for Standardization)所制定而发布的视频、音频、数据的压缩标准。

MPEG标准的视频压缩编码技术主要利用了具有运动补偿的帧间压缩编码技术以减小时间冗余度,利用DCT技术以减小图像的空间冗余度,利用熵编码则在信息表示方面减小了统计冗余度。这几种技术的综合运用,大大增强了压缩性能。

MPEG的缔造者们原先打算开发四个版本:MPEG1-MPEG4,以适用于不同带宽和数字影像质量的要求。后由于MPEG3被放弃,所以现存只有三个版本的MPEG:MPEG-1,MPEG-2,MPEG-4。总体来说,MPEG在三方面优于其他压缩/解压缩方案。首先,由于在一开始它就是做为一个国际化的标准来研究制定,所以,MPEG具有很好的兼容性。其次,MPEG能够比其他算法提供更好的压缩比,最高可达200:1。更重要的是,MPEG在提供高压缩比的同时,对数据的损失很小。

MPEG-1

MPEG-1制定于1992年,为工业级标准而设计,可适用于不同带宽的设备,如CD-ROM、Video-CD、CD-i。它可针对SIF标准分辨率(对于NTSC制为352X240;对于PAL制为352X288)的图象进行压缩,传输速率为1.5Mbits/sec,每秒播放30帧,具有CD(指激光唱盘)音质,质量级别基本与VHS相当。MPEG的编码速率最高可达4-5Mbits/sec,但随着速率的提高,其解码后的图象质量有所降低。 M PEG-1也被用于数字电话网络上的视频传输,如非对称数字用户线路(ADSL),视频点播(VOD),以及教育网络等。同时,MPEG-1也可被用做记录媒体或是在INTERNET上传输音频。

MPEG-2

MPEG-2制定于1994年,设计目标是高级工业标准的图象质量以及更高的传输率。MPEG-2所能提供的传输率在3-10Mbits/sec间,其在NTSC制式下的分辨率可达720X486,MPEG-2也可提供并能够提供广播级的视像和CD级的音质。MPEG-2的音频编码可提供左右中及两个环绕声道,以及一个加重低音声道,和多达7个伴音声道(DVD可有8种语言配音的原因)。由于MPEG-2在设计时的巧妙处理,使得大多数MPEG-2解码器也可播放MPEG-1格式的数据,如VCD。

同时,由于MPEG-2的出色性能表现,已能适用于HDTV,使得原打算为HDTV设计的MPEG-3,还没出世就被抛弃了。(MPEG-3要求传输速率在20Mbits/sec-40Mbits/sec间,但这将使画面有轻度扭曲)。除了做为DVD的指定标准外,MPEG-2还可用于为广播,有线电视网,电缆网络以及卫星直播(DirectBroadcastSatellite)提供广播级的数字视频。

MPEG-2的另一特点是,其可提供一个较广的范围改变压缩比,以适应不同画面质量,存储容量,以及带宽的要求。

对于最终用户来说,由于现存电视机分辨率限制,MPEG-2所带来的高清晰度画面质量(如DVD画面)在电视上效果并不明显,到是其音频特性(如加重低音,多伴音声道等)更引人注目。

MPEG-4

MPEG专家组的专家们正在为MPEG-4的制定努力工作。MPEG-4标准主要应用于视像电话(videophone),视像电子邮件(VideoEmail)和电子新闻(Electronicnews)等,其传输速率要求较低,在4800-64000bits/sec之间,分辨率176X144。MPEG-4利用很窄的带宽,通过帧重建技术,压缩和传输数据,以求以最少的数据获得最佳的图象质量。

与MPEG-1和MPEG-2相比,MPEG-4的特点是其更适于交互AV服务以及远程监控。MPEG-4是第一个使你由被动变为主动(不再只是观看,允许你加入其中,即有交互性)的动态图象标准;它的另一个特点是其综合性;从根源上说,MPEG-4试图将自然物体与人造物体相溶合(视觉效果意义上的)。MPEG-4的设计目标还有更广的适应性和可扩展性。

MPEG-1

MPEG-1是MPEG组织制定的第一个视频和音频有损压缩标准。视频压缩算法于1990年定义完成。1992年底,MPEG-1正式被批准成为国际标准。MPEG-1是为CD光碟介质定制的的视频和音频压缩格式。一张70分钟的CD光碟传输速率大约在1.4Mbps。而MPEG-1采用了块方式的运动补偿、离散余弦变换(DCT)、量化等技术,并为1.2Mbps传输速率进行了优化。MPEG-1随后被Video CD采用作为核心技术。MPEG-1的输出质量大约和传统录像机VCR,信号质量相当,这也许是Video CD在发达国家未获成功的原因。

特点

MPEG-1是为CD光盘介质定制的视频和音频压缩格式。一张70分钟的CD光盘传输速率大约在1.4Mbps。而MPEG-1采用了块方式的运动补偿、离散余弦变换(DCT)、量化等技术,并为1.2Mbps传输速率进行了优化。MPEG-1随后被Video CD采用作为核心技术。VCD的分辨率只有约352×240,并使用固定的比特率(1.15Mbps),因此在播放快速动作的视频时,由于数据量不足,令压缩时宏区块无法全面调整,结果使视频画面出现模糊的方块。因此MPEG-1的输出质量大约和传统录像机VCR相当,这也许是Video CD在发达国家未获成功的原因。MPEG-1音频分三代,其中最著名的第三代协议被称为MPEG-1 Layer 3,简称MP3,已经成为广泛流传的音频压缩技术。MPEG-1音频技术在每一代之间,在保留相同的输出质量之外,压缩率都比上一代高。第一代协议MP1被应用在LD作为记录数字音频以及飞利浦公司的DGC上;而第二代协议MP2后来被应用于欧洲版的DVD音频层之一。

MPEG-1具有以下特点:

  • 随机访问
  • 灵活的帧率
  • 可变的图像尺寸
  • 定义了I-帧、P-帧和B-帧
  • 运动补偿可跨越多个帧
  • 半像素精度的运动向量
  • 量化矩阵
  • GOF结构
  • slice结构

音频分层

MPEG-1音频分三层,分别为MPEG-1 Layer1,MPEG-Layer2以及MPEG-Layer3,并且高层兼容低层。其中第三层协议被称为MPEG-1 Layer 3,简称MP3。MP3已经成为广泛流传的的音频压缩技术。

  • MPEG-1 Layer1采用每声道192kbit/s,每帧384个样本,32个等宽子带,固定分割数据块。子带编码用DCT(离散余弦变换)和(快速傅立叶变换)计算子带信号量化bit数。采用基于频域掩蔽效应的心理声学模型,使量化噪声低于掩蔽值。量化采用带死区的线性量化器,主要用于数字盒式磁带(DCC)。
  • MPEG-1 Layer2采用每声道128kbit/s,每帧1152个样本,32个子带,属不同分帧方式。采用共同频域和时域掩蔽效应的心理声学模型,并对高、中,低频段的比特分配进行限制,并对比特分配、比例因子,取样进行附加编码。Layer2 广泛用于数字电视,CD-ROM,CD-I和VCD等。
  • MPEG-1 Layer3采用每声道64kbit/s,用混合滤波器组提高频率分辨率,按信号分辨率分成6X32或18X32个子带,克服平均32个子带的Layer1,Layer2在中低频段分辨率偏低的缺点。采用心理声学模型2,增设不均匀量化器,量化值进行熵编码。主要用于ISDN(综合业务数字网)音频编码。

MPEG-1制定于1992年,为工业级标准而设计,它可针对SIF标准分辨率(对于NTSC制为352X240;对于PAL制为352X288)的图像进行压缩,传输速率为1.5Mbits/sec,每秒播放30帧,具有CD(指激光唱盘)音质,质量级别基本与VHS相当。MPEG的编码速率最高可达4- 5Mbits/sec,但随着速率的提高,其解码后的图象质量有所降低。 MPEG-1也被用于数字电话网络上的视频传输,如非对称数字用户线路(ADSL),视频点播(VOD),以及教育网络等。同时,MPEG-1也可被用做记录媒体或是在INTERNET上传输音频。

MPEG-2

MPEG-2是MPEG(Moving Picture Experts Group,运动图像专家组)组织制定的视频和音频有损压缩标准之一,它的正式名称为“基于数字存储媒体运动图像和语音的压缩标准”。与MPEG-1标准相比,MPEG-2标准具有更高的图像质量、更多的图像格式和传输码率的图像压缩标准。MPEG-2标准不是MPEG-1的简单升级,而是在传输和系统方面做了更加详细的规定和进一步的完善。它是针对标准数字电视和高清晰电视在各种应用下的压缩方案,编码率从3 Mbit/s~100 Mbit/s。

MPEG-2音频是在1994年11月为数字电视而提出来的,其发展分为三个阶段: 第一阶段是对MPEG-1增加了低采样频率,有16KHZ,22.05KHZ,以及24KHZ。 第二阶段是对MPEG-1实施了向后兼容的多声道扩展,将其称为MPEG-2 BC。支持单声道,双声道,多声道等编码。并附加“低频加重”扩展声道,从而达到五声道编码。 第三阶段是向后不兼容,将其称为MPEG-2 AAC先进音频编码。采样频率可以低至8KHZ;而高至96KHZ范围内的1-48个通道可选的高音质音频编码。

分部

MPEG-2标准目前分为9个部分,统称为ISO/IEC13818国际标准。各部分的内容描述如下:

  • 一部分-ISO/IEC13818-1,System:系统,描述多个视频,音频和数据基本码流合成传输码流和节目码流的方式。
  • 二部分-ISO/IEC13818-2,Video:视频,描述视频编码方法。
  • 三部分-ISO/IEC13818-3,Audio:音频,描述与MPEG-1音频标准反向兼容的音频编码方法。
  • 四部分-ISO/IEC13818-4,Compliance:符合测试,描述测试一个编码码流是否符合MPEG-2码流的方法。
  • 五部分-ISO/IEC13818-5,Software:软件,描述了MPEG-2标准的第一、二、三部分的软件实现方法。
  • 六部分-ISO/IEC13818-6,DSM-CC:数字存储媒体-命令与控制,描述交互式多媒体网络中服务器与用户间的会话信令集。

上六个部分均已获得通过,成为正式的国际标准,并在数字电视等领域中得到了广泛的实际应用。此外,MPEG-2标准还有三个部分:

  • 第七部分规定不与MPEG-1音频反向兼容的多通道音频编码;
  • 第八部分现已停止;
  • 第九部分规定了传送码流的实时接口。

1990年成立的ATM视频编码专家组与MPEG在ISO/IEC13818标准的第一和第二两个部分进行了合作,因此上述两个部分也成为ITU-T的 标准,分别为:ITU-T H.222.0和ITU-T H.262视频。

MPEG-4

MPEG-4,于MP4是一套用于音频、视频信息的压缩编码标准,由国际标准化组织(ISO)和国际电工委员会(IEC)下属的“动态图像专家组(Moving Picture Experts即MPEG制定,第一版在1998年10月通过,第二版在1999年12月通过。MPEG-4格式的主要用途在于网上流、光盘、语音发送(视频电话),以及电视广播。MPEG-4包含了MPEG-1及MPEG-2的绝大部份功能及其他格式的长处,并加入及扩充对虚拟现实模型语言(VRML,VirtualReality Modeling Language)的支持,面向对象的合成档案(包括音效,视讯及VRML对象),以及数字版权管理(DRM)及其他互动功能。而MPEG-4比MPEG-2更先进的其中一个特点,就是不再使用宏区块做影像分析,而是以影像上个体为变化记录,因此尽管影像变化速度很快、码率不足时,也不会出现方块画面。

分部

MPEG-4由一系列的子标准组成,被称为部(part)(有时也译为卷),包括以下的部分:

  • 第一部分(ISO/IEC14496-1):系统:描述视讯和音频数据流的控制、同步以及混合方式(即混流Multiplexing,简写为MUX)。
  • 第二部分(ISO/IEC14496-2):视讯:定义了一个对各种视觉讯息(包括自然视讯、静止纹理、计算机合成图形等等)的编译码器。(例如XviD编码就属于MPEG-4Part2)
  • 第三部分(ISO/IEC14496-3):音讯:定义了一个对各种音频讯号进行编码的编译码器的集合。包括高阶音频编码(AdvancedAudioCoding,缩写为AAC)的若干变形和其他一些音频/语音编码工具。
  • 第四部分(ISO/IEC14496-4):一致性:定义了对本标准其他的部分进行一致性测试的程序。
  • 第五部分(ISO/IEC4496-5):参考软件:提供了用于演示功能和说明本标准其他部分功能的软件。
  • 第六部分(ISO/IEC14496-6):多媒体传输整合框架(DMIF for Delivery Multimedia IntegrationFramework)
  • 第七部分(ISO/IEC14496-7):优化的参考软件:提供了对实作进行优化的例子(这里的实作指的是第五部分)。
  • 第八部分(ISO/IEC14496-8):在IP网络上传输:定义了在IP网络上传输MPEG-4内容的方式。
  • 第九部分(ISO/IEC14496-9):参考硬件:提供了用于演示怎样在硬件上实作本标准其他部分功能的硬件设计方案。
  • 第十部分(ISO/IEC14496-10):进阶视讯编码或称高阶视讯编码(Advanced Video Coding,缩写为AVC):定义了一个视讯编译码器(codec)。AVC和XviD都属于MPEG-4编码,但由于AVC属于MPEG-4Part10,在技术特性上比属于MPEG-4Part2的XviD要先进。另外,它和ITU-TH.264标准是一致的,故又称为H.264。
  • 第十二部分(ISO/IEC14496-12):基于ISO的媒体文件格式:定义了一个储存媒体内容的文件格式。
  • 第十三部分(ISO/IEC14496-13):知识产权管理和保护(IPMP for Intellectual Property Management andProtection)拓展。
  • 第十四部分(ISO/IEC14496-14):MPEG-4文件格式:定义了基于第十二部分的用于储存MPEG-4内容的视讯文件格式。
  • 第十五部分(ISO/IEC14496-15):AVC文件格式:定义了基于第十二部分的用于储存第十部分的视讯内容的文件格式。
  • 第十六部分(ISO/IEC14496-16):动画框架扩充功能(AFX:Animation Framework eXtension)。
  • 第十七部分(ISO/IEC14496-17):同步文字字幕格式。
  • 第十八部分(ISO/IEC14496-18):字型压缩和串流传输(针对开放字型格式 Open Font Format)。
  • 第十九部分(ISO/IEC14496-19):合成材质流(Synthesized Texture Stream)。
  • 第二十部分(ISO/IEC14496-20):简单场景表示(LASeR for Lightweight Scene Representation。
  • 第二十一部分(ISO/IEC14496-21):用于描绘(Rendering)的MPEG-J拓展。
  • 第二十二部分(ISO/IEC14496-22):开放字型格式(Open Font Format)。
  • 第二十三部分(ISO/IEC14496-23):符号化音乐表示(Symbolic Music Representation)。
  • 第二十四部分(ISO/IEC14496-24):音频与系统互动作用(Audio and systems interaction)。
  • 第二十五部分(ISO/IEC14496-25):3D图形压缩模型(3D GraphicsCompression Model)。
  • 第二十六部分(ISO/IEC14496-26):音讯一致性检查:定义了测试音频数据与ISO/IEC 14496-3是否一致的方法(Audioconformance)。
  • 第二十七部分(ISO/IEC14496-27):3D图形一致性检查:定义了测试3D图形数据与ISO/IEC14496-11:2005,ISO/IEC 14496-16:2006,ISO/IEC14496-21:2006,和ISO/IEC14496-25:2009是否一致的方法(3D Graphicsconformance)。

Profiles是在每个部分内定义的,所以对某个部分的一个实作通常不是对该部分的完整实作。

特点

  • 对于不同的对象可采用不同的编码算法,从而进一步提高压缩效率;
  • 对象各自相对独立,提高了多媒体数据的可重用性;
  • 允许用户对单个的对象操作,提供前所未有的交互性;
  • 允许在不同的对象之间灵活分配码率,对重要的对象可分配较多的字节,对次要的对象可分配较少的字节,从而能在低码率下获得较好的效果;
  • 可以方便的集成自然音视频对象和合成音视频对象。

MPEG-7

引用

Moving Picture Experts Group ISO/IEC JTC 1/SC 29 MPEG-1 MPEG-2 MPEG-4 MP3

基于深度学习的自动抠图

发表于 2018-01-25 | 分类于 ml

资源

  • 原文:Background removal with deep learning
  • 译文:自拍抠图抠到手软?详解如何用深度学习消除背景
  • server代码地址
  • acGAN-Paper-Implementation:acGAN paper implementation and adaptation by KJeanclaude & Gidi Shperber
  • fast.ai course
  • 作者:Alon Burg ,Gidi Shperber

deep-photo-styletransfer介绍

发表于 2018-01-21 | 分类于 ml

1.介绍

deep-photo-styletransfer:

2.安装

环境为mac10.13.2

2.1安装依赖

2.1.1 Torch

Torch是基于Lua语言的深度学习框架. 安装:

1
2
3
curl -s https://raw.githubusercontent.com/torch/ezinstall/master/install-deps | bash
git clone https://github.com/torch/distro.git ~/torch --recursive
cd ~/torch; ./install.sh

第一条命令安装了LuaJIT 和 Torch的依赖库。第二条命令安装LuaJIT, LuaRocks,然后用 LuaRocks (lua 包管理工具)安装核心包:torch, nn and paths, 和其它包。上面命令把 torch 加入到了你的PATH环境变量中了,用 source 更新一下让环境变量生效:

1
2
3
4
5
6
# 在 Linux 上
source ~/.bashrc
# 在 OSX 上
source ~/.profile
或
source ~/.bash_profile

如果你想要卸载 torch,执行:

1
rm -rf ~/torch

现在在你可以用 Luarocks 安装新的包

1
2
luarocks install image
luarocks list

安装完之后,你可以在终端用 th 命令运行 torch,现在进入了 torch 的交互模式,类似Python的交互模式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ th

______ __ | Torch7
/_ __/__ ________/ / | Scientific computing for Lua.
/ / / _ / __/ __/ _ |
/_/ ___/_/ __/_//_/ | https://github.com/torch
| http://torch.ch

th> torch.Tensor{1,2,3}
1
2
3
[torch.DoubleTensor of dimension 3]

th>

要退出交互模式,两次Ctrl+C,或输入 os.exit()。 要执行 file.lua, 写 th> dofile “file.lua”。 在非交互模式下执行文件:

1
th file.lua

th 命令有很多选项,类似 perl 和 ruby。

1
2
3
4
5
6
7
8
9
10
11
12
13
$ th -h
Usage: th [options] [script.lua [arguments]]

Options:
-l name load library name
-e statement execute statement
-h,--help print this help
-a,--async preload async (libuv) and start async repl (BETA)
-g,--globals monitor global variables (print a warning on creation/access)
-gg,--gglobals monitor global variables (throw an error on creation/access)
-x,--gfx start gfx server and load gfx env
-i,--interactive enter the REPL after executing a script
Share the post "Mac OS X/Ubuntu 安装 Torch"

安装deep-photo-styletransfer所需依赖:

  • matio-ffi:luarocks install matio-ffi
  • loadcaffe:luarocks install loadcaffe
2.1.2Matlab or Octave

Matlab较大,而且是商用软件,所以选择了octave Octave是一款用于数值计算和绘图的开源软件, 精于矩阵运算:求解联立方程组、计算矩阵特征值和特征向量等等,并能够通过多种形式将数据可视化。Octave最简单的使用方式就是像使用一个计算器一样在命令提示符下输入相应的计算式。Octave能识别通常的计算表达式。例如,在终端输入

1
octave:##>2+2

mac下首先确保自己的Mac安装了Xcode和Command Line Tool,通过以下命令安装Command Line Tool,

1
xcode-select --install

之后安装Mac下的包管理神器Homebrew,命令如下,

1
curl -LsSf http://github.com/mxcl/homebrew/tarball/master | sudo tar xvz -C/usr/local --strip 1

通过以下命令升级Homebrew:

1
sudo brew update && sudo brew upgrade

之后通过以下命令安装gcc、XQuartz,最后就可以通过Homebrew安装Octave了,

1
2
3
sudo brew install gcc
sudo brew install Caskroom/cask/xquartz
sudo brew install octave

mac下使用brew安装的octave是4.2版本,使用imread等函数时会提示:

1
2
3
4
5
error: Magick++ exception: octave-cli-4.2: Unable to access configuration file (delegates.mgk) reported by magick/blob.c:2101 (GetConfigureBlob)
error: called from
__imread__ at line 80 column 10
imageIO at line 117 column 26
imread at line 106 column 30

未找到原因,最后在https://wiki.octave.org/Octave_for_macOS#Simple_Installation_Instructions_2中下载[Mac OS X Bundle](https://sourceforge.net/projects/octave/files/Octave%20MacOSX%20Binary/2016-07-11-binary-octave-4.0.3/octave_gui_403_appleblas.dmg/download)中下载[4.0.3-gui](https://jaist.dl.sourceforge.net/project/octave/Octave%20MacOSX%20Binary/2016-07-11-binary-octave-4.0.3/octave_gui_403_appleblas.dmg)及[4.0.2 command line](https://jaist.dl.sourceforge.net/project/octave/Octave%20MacOSX%20Binary/2016-06-06-binary-octave-4.0.2/octave_cli_402.dmg)执行imread会出现:

1
warning: your version of GraphicsMagick limits images to <16> bits per pixel

根据GraphicsMagick中介绍是GraphicsMagick编译是参数不对,后下载(地址)使用

1
2
3
4
./configure --with-quantum-depth=16 --enable-shared --disable-static --with-magick-plus-plus=yes
make
make check
sudo make install

仍然不对,好像bound包依赖的库不是默认安装路径的. 使用最新的GraphicsMagick为1.3.27,命令行下可以使用gm命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ gm
GraphicsMagick 1.3.27 Q32 http://www.GraphicsMagick.org/
Copyright (C) 2002-2017 GraphicsMagick Group.
Additional copyrights and licenses apply to this software.
See http://www.GraphicsMagick.org/www/Copyright.html for details.
Usage: gm command [options ...]

Where commands include:
batch - issue multiple commands in interactive or batch mode
benchmark - benchmark one of the other commands
compare - compare two images
composite - composite images together
conjure - execute a Magick Scripting Language (MSL) XML script
convert - convert an image or sequence of images
help - obtain usage message for named command
identify - describe an image or image sequence
mogrify - transform an image or sequence of images
montage - create a composite image (in a grid) from separate images
time - time one of the other commands
version - obtain release version

可以使用pkg install -forge package安装Octave-Forge 中的包,如默认使用的image包:

1
pkg install -forge image

也可以下载其他版本的image包到本地执行pkg install image-2.4.1.tar.gz pkg list可列出已安装的包,安装好后不能直接使用,使用前要load

1
warning: the 'col2im' function belongs to the image package from Octave Forge which you have installed but not loaded.  To load the package, run 'pkg load image' from the Octave prompt.

有人使用docker容器解决了这个问题:https://github.com/martinbenson/deep-photo-styletransfer, 但是未尝试

GraphicsMagick UNIX/Cygwin/MinGW Compilation octave-devel 3.6.3 GraphicsMagick limits images to 8 bits per pixel Octave教程 Octave Tutorial Octave requirements Is removing the Matlab dependency possible? Added Matlab dependency alternative Re: [GM-apis] PythonMagick

2.1.3CUDA cudnn

从NVIDIA cuDNN官网下载,文档地址

  • 7.5下载地址
  • 9.1下载地址 使用不同版本有兼容性问题
2.1.4下载VGG-19
1
sh models/download_models.sh
2.1.5Compile cuda_utils.cu (Adjust PREFIX and NVCC_PREFIX in makefile for your machine)

遇到问题:

1
THC.h includes THCGeneral.h, does not exist

解决:

1
2
3
4
I've fixed this issue by executing the following commands in terminal:

cd to you torch directory, and execute the update.sh script
second, execute "luarocks install cutorch"

可能有xcode Command Line Tool版本不兼容问题:

1
nvcc fatal : The version ('80100') of the host compiler ('Apple clang') is not supported

替换版本即可:

1
2
3
4
5
登录 https://developer.apple.com/downloads/
下载Xcode CLT (Command Line Tools) 8.2
安装 CLT
执行 sudo xcode-select --switch /Library/Developer/CommandLineTools
输入命令行查看clang版本 clang --version

THC.h includes THCGeneral.h, does not exist

相关资源

  • 深度摄影风格转换–Deep Photo Style Transfer
  • cuDNN
  • CUDA从入门到精通
  • VGG论文笔记
  • deep-photo-styletransfer-tf:Tensorflow (Python API) implementation of Deep Photo Style Transfer
  • floydhub/deep-photo-styletransfer:Jupyter Notebook to train photorealistic style transfer
  • How do I rebuild Octave and link in GraphicsMagick?
  • /gnu/octave/ 的索引

相关问题

  1. configure :error: No usable version of sed found: I did ./configure to make a makefile

but it ran into an error: configure :error: No usable version of sed found:

I then typed which see

it shows /usr/bin/sed.

so, what’s wrong? why can’t ./configure find sed?

I happened to have this problem on my mac. This is because OS X uses an old version of sed. Installing gnu-sed by brew install gnu-sed and alias gsed=sed solved this problem. You may install gnu-sed with other method.

https://stackoverflow.com/questions/26351285/configure-error-no-usable-version-of-sed-found

  1. gm-bin convert: Unable to access configuration file (delegates.mgk) [No such file or directory].

I am attempting to install GraphicsMagick in a hosting account…

I used this info to get it to work in most cases:

How do you specify the location of libraries to a binary? (linux)

However, it still cannot find the delegates.mgk (which is in ./lib/GraphicsMagick-1.3.14/delegates.mgk) as witnessed in this error:

gm-bin convert: Unable to access configuration file (delegates.mgk) [No such file or directory].

Either, a) how do find out where the binary thinks this file should be, or b) how do I extend the wrapper script to help it out?

Figured it out after looking through the binary for /PATH/

The binaries require these additional path variables:

1
2
3
$MAGICK_CONFIG_PATH
$MAGICK_CODER_MODULE_PATH
$MAGICK_FILTER_MODULE_PATH

…here is the resulting script modification form my setup:

1
2
3
4
5
6
7
8
9
10
11
#!/bin/sh
if [ -n "$LD_LIBRARY_PATH" ]; then
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/USER/lib
else
LD_LIBRARY_PATH=/home/USER/lib
fi
[ -z "${MAGICK_CONFIGURE_PATH}" ] && export MAGICK_CONFIGURE_PATH=/home/USER/lib/GraphicsMagick-1.3.14/config
[ -z "${MAGICK_CODER_MODULE_PATH}" ] && export MAGICK_CODER_MODULE_PATH=/home/USER/lib/GraphicsMagick-1.3.14/modules-Q8/coders
[ -z "${MAGICK_FILTER_MODULE_PATH}" ] && export MAGICK_FILTER_MODULE_PATH=/home/USER/lib/GraphicsMagick-1.3.14/modules-Q8/filters
export LD_LIBRARY_PATH
exec /home/USER/bin/gm-bin "$@"
1…91011…19
轻口味

轻口味

190 日志
27 分类
63 标签
RSS
GitHub 微博 豆瓣 知乎
友情链接
  • SRS
© 2015 - 2019 轻口味
京ICP备17018543号
本站访客数 人次 本站总访问量 次