Will there be ghost in machine?

上周写完 I, self, mind, immortality and death 之后,在 Comment 里收到了推荐「Ghost in the Shell」(攻殻機動隊)的留言,所以就跑去看了~不得不说在发现原著是 1989 年开始连载的时候,真的震撼了,原来在那么早之前就已经有对这些问题的各种讨论了∑(゚Д゚)

「Ghost in the Shell」在整体贯穿主线的同时,每集故事探讨的话题相对独立,所以其实有很多可以聊的点。比如宗教对于人体「cyborg / 机械义体 / 电子脑」化的态度;cyborg 社会中的各种问题 —— 阶层、贫富、难民、电子毒品等;电子脑化之后自己的记忆、视觉都可能被轻易地被 Hack,那么什么才是真实与自我?

回到作品名本身 ——「Ghost in the Shell」—— 躯壳中的灵魂

「Ghost」一詞也是《攻殼機動隊》中的術語,指義體無法複製代表人類個性的意識。人造的義體、假肢、電子腦不過只是「shell」——一個空殼,無法複製的Ghost才是真正定義每個人存在的「靈魂」,沒有Ghost的機器人或者仿生人僅僅是由人工智慧驅動的哲學殭屍,並不是真正的人類。《攻殼機動隊》世界中的義體化、電子化人類就相當於「Ghosts in shells」——棲息在人造軀殼裡的人類意識。—— https://zh.wikipedia.org/zh-tw/攻殼機動隊

在看完第一季「Ghost in the Shell: Stand Alone Complex」和第二季「Ghost in the Shell: S.A.C 2nd GIG」之后,印象最深的还是 9 台萌物们 —— 思考战车「タチコマ」(塔奇克马)。在第一季中萌物们有过如下对话

「廢棄處分等於死亡嗎?」—— タチコマ D

「在我們可能體驗到的領域中,並沒有死亡這一項,所以也不能這麼說…」—— タチコマ A

「這就是我們這種沒有靈魂的AI的極限吧,怎麼說都是半不死身。不算活著,所以也不會死」—— タチコマ C

「沒錯,果然是因為我們沒有靈魂才會引發這種種的問題」—— タチコマ A

「廢棄處分應該不等於死亡吧」—— タチコマ B

「咦?是這樣嗎?」—— タチコマ E

「物理性身體以及靈魂,必須不多不少完全一致的時代,早就結束了。極端的說,沒有身體的資料集合體也並非完全不可能孕育出靈魂」—— タチコマ B

……

「我問你,你覺得「活著」是怎麼一回事呢?」—— タチコマ E

「嗯…這個嘛,「生命」這個字的定義本身就是流動的」—— タチコマ B

「怎麼說?」—— タチコマ E

「因為跟機器人有了接觸,人類對生命的印象在不知不覺中產生改變。不過發生變化的不是機器人,反而應該說是人類那邊吧」—— タチコマ B

——「Ghost in the Shell: Stand Alone Complex」Episode 15, 08:30 - 09:54

先说说其中那句「物理性身體以及靈魂,必須不多不少完全一致的時代,早就結束了。極端的說,沒有身體的資料集合體也並非完全不可能孕育出靈魂」。这两天正好看到了一张图 ——

The nervous system. That is us...the rest of the body is an organic spacesuit worn by this creature to live on this particular rock revolving around a star.

(人类的)神经系统。那就是我们……身体的其余部分只是这种生物为了居住在那个环绕着一颗恒星转的巨大岩石上而穿着的有机太空服而已。

Continue reading Will there be ghost in machine?

A Simple Approach to Add Invisible Watermark with OpenCV

摸鱼摸鱼,今天试试用简单的频域隐写水印~

其实隐写水印的方法也有不少了,这里是其中一个简单的方法,使用的是离散傅立叶变换,相比起小波变换的版本,这里的鲁棒性没有那么强,但也还是挺好玩的,下次有时间可以试试看小波变换的方法233333

在频域增加水印的好处是肉眼不易看见,而且对于一般的裁剪、拉伸、涂抹有较强的抵抗性~比如下面的图像就加上隐写的水印,但是与左侧的原图几乎没有视觉上的差异。

在将两张图转换到频域上之后,则一眼能看到右侧图上的水印~

Continue reading A Simple Approach to Add Invisible Watermark with OpenCV

Add Image Zoom In/Out Feature with medium-zoom.js

啊,这篇 post 大概是个笔记~

其实很久之前就想把放大缩小图片的功能加到博客上来的,然而一直以来都在摸鱼,前段时间帮玲做了一个摄影的的博客,于是就正好找找看有没有合适又好用的 JS 项目

在一番搜索和试用 Demo 之后,只有 https://github.com/francoischalifour/medium-zoom 最符合需求,同时使用起来非常便利,几行代码就可以给博客加上图片放大缩小的功能

Continue reading Add Image Zoom In/Out Feature with medium-zoom.js

C/C++ 中非法的 void main() 与 main() 函数返回值的作用

这篇 post 是主要是写给 Association of Robots and Artificial Intelligence 的小伙伴的~主要说说为什么 void main() 是非法的,以及 main() 函数的返回值到底有什么用~

先从 void main() 讲起吧~这里就先引用 C++ 之父,Bjarne Stroustrup,在他的博客中写过的一篇问答:Can I write "void main()"?

Can I write "void main()"?

The definition
                                      void main() { /* ... */ }
is not and never has been C++, nor has it even been C. See the ISO C++ standard 3.6.1[2] or the ISO C standard 5.1.2.2.1. A conforming implementation accepts
                                      int main() { /* ... */ }
and
                                      int main(int argc, char* argv[]) { /* ... */ }
A conforming implementation may provide more versions of main(), but they must all have return type int. The int returned by main() is a way for a program to return a value to "the system" that invokes it. On systems that doesn't provide such a facility the return value is ignored, but that doesn't make "void main()" legal C++ or legal C. Even if your compiler accepts "void main()" avoid it, or risk being considered ignorant by C and C++ programmers.

翻译:这种写法 void main() { /* ... */ },从来都没有在 C/C++ 中存在过,根据 ISO C++ 标准 3.6.1 或者 ISO C 标准 5.1.2.2.1,只有 int main() {/* ... */} 或者是 int main(int argc, char* argv[]) {/* ... */} 才是可接受的。

A conforming implementation may provide more versions of main(), but they must all have return type int. The int returned by main() is a way for a program to return a value to “the system” that invokes it. On systems that doesn’t provide such a facility the return value is ignored, but that doesn’t make “void main()” legal C++ or legal C. Even if your compiler accepts “void main()” avoid it, or risk being considered ignorant by C and C++ programmers. —— Bjarne Stroustrup

翻译:符合规范的写法可能会有一些别的版本,但是他们都必须返回 int。这个main()返回的 int是用来会返回给调用这个程序的“系统”的。在没有提供这样的功能的系统中,这个返回值会被忽略,但是那也绝不使得void main在 C/C++ 中是合法的。即便你的编译器让你编译过了,或者就是仔细考虑过这么写的后果/风险

比如,我们来编译一下如下的 C 代码

void main() {
    
}

那么编译时就会报一个警告

编译器告诉我们 main() 函数应该有的返回类型是 int 而不是 void

此外,void main() 也不在 C89 或者 ANSI C 规范中受支持,要么会报错,要么会产生警告。事实上,没有任何一个 C/C++ 标准支持这种形式的 main() 函数。以下是依次以 C89 标准和 ANSI C 标准编译时会有的输出。

Continue reading C/C++ 中非法的 void main() 与 main() 函数返回值的作用

Python 2.7 + Scripting Bridge 导出 iTunes Library 里音乐的 MetaInfo 与封面到 MongoDB

作为某个 Project 的一部分~(暂时不透露是什么,嘻嘻(⁎⁍̴̛ᴗ⁍̴̛⁎) ) 需要把 iTunes 里面的所有音乐的 MetaInfo 和封面导出到 MongoDB 中

MongoDB 上次已经已经在 Raspberry Pi 4 上编译部署好了~在 Raspberry Pi 4 上安装 64-bit MongoDB Server 服务

然后再配合很久以前玩过的 在 Python 里使用 Scripting Bridge 与 iTunes 交互,就可以达到目标了233333

当然需要注意的是,这里要使用的是 macOS 自带的 Python 2.7,因为 ScriptingBridge 只安装在了自带的 Python 2.7 里

真正代码的话,其实整体来说很简单,需要考虑的点是如何做到不重复写封面,因为——

  1. 目前 Scripting Bridge 与 iTunes 交互时,只能一首音乐一首音乐的依次遍历,不能直接按照专辑遍历
  2. 同一张专辑里,有的音乐可能包含多张封面
  3. 不同的专辑可能被我 assgin 过相同的封面

综合这几点考虑的话,那就只能每次拿到有封面的音乐之后,对它的每一张封面都计算 SHA256 摘要(这里暂且认为 SHA256 的空间足够大,不会产生碰撞),并在放进 global_sha256 前,检查是否已经有相同的 SHA256 存在其中。如果没有的话,才保存图片到磁盘中,并放到那首歌的 MetaInfo 中;如果在 global_sha256 中有的话,那么就再看那首歌的 MetaInfo 中有没有这个 SHA256(因为也许有人不小心添加了两张一样的封面到音乐里)。

在遍历完所有音乐之后,把这些 MetaInfo 写入到 JSON 文件中~(就像下面这样

{
  "album": "Cutie Panther", 
  "name": "夏、終わらないで。", 
  "artist": "BiBi (南條愛乃, Pile, 徳井青空)", 
  "cover": [
    "44f9b56091c7ca5b011cd9cb306eab21d4f854300c96347a0a7f3538cbeb9dcd-1"
  ], 
  "composer": "渡辺和紀", 
  "year": 0, 
  "sha256": [
    "44f9b56091c7ca5b011cd9cb306eab21d4f854300c96347a0a7f3538cbeb9dcd"
  ]
}

最后再导进 MongoDB 数据库就可以啦(当然需要安装一下 pymongo 库)~主要的就分为 2 个 stage ♪(´ε` )

python2.7 -m pip install --user pymongo
python2.7 iTunes.py -s 1
python2.7 iTunes.py --host raspberrypi.local -s 2
Continue reading Python 2.7 + Scripting Bridge 导出 iTunes Library 里音乐的 MetaInfo 与封面到 MongoDB

在 Raspberry Pi 4 上部署 Apache 2 + PHP 7 + MongoDB

在前面几天终于把 64-bit MongoDB Server 折腾编译好之后,现在就可以在 Raspberry Pi 上部署 Apache 2 + PHP 7 + MongoDB 的环境了~

编译和安装可以参考之前两篇post~在 Raspberry Pi 4 上编译 64-bit 的 MongoDB Server在 Raspberry Pi 上安装 64-bit MongoDB Server 服务

那么现在就是接着在上次的 chroot 环境里部署 Apache 2 + PHP 7,以及 PHP 的 MongoDB 接口~

  1. 安装 Apache 2 与设置 Systemd Service 启动 chroot 环境下的 Apache 2
  2. 安装 PHP 7 与编译设置 PHP MongoDB 扩展
Continue reading 在 Raspberry Pi 4 上部署 Apache 2 + PHP 7 + MongoDB

Solution for "dpkg: unknown user / system group in statoverride file"

When I was deploying my Raspberry Pi for my new project, dpkg reported a unrecoverable fatal error while installing dependencies,

dpkg: unrecoverable fatal error, aborting:
 unknown system group 'ssl-cert' in statoverride file; the system group got removed
before the override, which is most probably a packaging bug, to recover you
can remove the override manually with dpkg-statoverride
E: Sub-process /usr/bin/dpkg returned an error code (2)

So I had a look at the file /var/lib/dpkg/statoverride

Since dpkg said that the system group ssl-cert was already removed, and to recover I need to remove these entries with ssl-cert.

Then it was time for sed, let's remove the lines containing ssl-cert

sed -i '/ssl-cert/d' /var/lib/dpkg/statoverride
Continue reading Solution for "dpkg: unknown user / system group in statoverride file"

macOS / Linux 上设置 Python 3 环境 —— MiniConda, pip3

这篇 post 是主要是写给 Association of Robots and Artificial Intelligence 的小伙伴的~如何在 macOS / Linux 上设置 Python 3 环境,包括如何使用 MiniConda 来让多个不同的 Python 3 或者 Python 2 环境共存,如何设置 pip 的镜像源等

  1. 下载 MiniConda 安装包
  2. 安装 MiniConda
  3. 设置 pip 使用清华大学 TUNA 镜像
  4. 设置一个 Python 3.8 的虚拟环境 py38
  5. 在 Python 3.8 虚拟环境中安装软件包
Continue reading macOS / Linux 上设置 Python 3 环境 —— MiniConda, pip3

在 Raspberry Pi 4 上安装 64-bit MongoDB Server 服务

啊,算是这个大坑的最后一篇了吧

前一篇是关于编译的,https://blog.0xbbc.com/2019/11/compile-64bit-mongodb-server-on-raspberry-pi-4/

那么在编译完之后,就是安装这个服务了~由于编译时绝大部分是静态链接的,因此上一篇编译出来之后,MongoDB Server r4.2.1 的体积在 2.2GB 左右,emmmmm,有点大。。总之,因为几乎都是静态链接,所以可以做个清洁安装~

Continue reading 在 Raspberry Pi 4 上安装 64-bit MongoDB Server 服务