2

在 OSX 上构建 pHash 0.9.4 可能会很棘手。对于那些遇到问题的人,我在下面的冗长回答可能会有所帮助。

4

1 回答 1

6


确保您的 macports 已完全更新并正常工作。这意味着最近的 Xcode,并在 Xcode 首选项->下载->组件中安装命令行工具!

$ sudo port selfupdate

# if you've had previous build issues:
$ sudo port clean --all

# get pHash
wget http://www.phash.org/releases/pHash-0.9.4.tar.gz
tar zxvf pHash-0.9.4.tar.gz
cd pHash-0.9.4

# remove old versions of ffmpeg, e.g.
$ sudo port installed ffmpeg
$ sudo port uninstall --follow-dependents ffmpeg @0.7.11_1+mmx
$ sudo port uninstall --follow-dependents ffmpeg @0.7.8_0

# install latest ffmpeg-devel version (@20120329 for me) - enable the non-free stuff as well
$ sudo port install ffmpeg-devel +nonfree

# double check that you have some new header files
$ ll -tr /opt/local/include/

total 8816
-rw-r--r--    1 root  admin      191 Dec 23  2004 lua.hpp
-rw-r--r--    1 root  admin     1026 Dec 27  2007 lualib.h
-rw-r--r--    1 root  admin     5777 Dec 27  2007 lauxlib.h
...

drwxr-xr-x    6 root  admin      204 Jul 12 17:27 libmodplug
drwxr-xr-x    3 root  admin      102 Jul 12 17:32 libswscale
drwxr-xr-x    3 root  admin      102 Jul 12 17:32 libswresample
drwxr-xr-x    3 root  admin      102 Jul 12 17:32 libpostproc
drwxr-xr-x   41 root  admin     1394 Jul 12 17:32 libavutil
drwxr-xr-x    5 root  admin      170 Jul 12 17:32 libavformat
drwxr-xr-x    8 root  admin      272 Jul 12 17:32 libavfilter
drwxr-xr-x    3 root  admin      102 Jul 12 17:32 libavdevice
drwxr-xr-x   10 root  admin      340 Jul 12 17:32 libavcodec

# get CImg and copy CImg.h into your pHash dir
$ cd ..
$ wget http://downloads.sourceforge.net/project/cimg/CImg-1.5.0.zip
$ unzip CImg-1.5.0.zip
$ cp CImg-1.5.0/CImg.h pHash-0.9.4/
$ cd pHash-0.9.4

# copy the JNI headers from your Java SDK into your pHash dir - for 1.7.0 they're here:
$ cp /Library/Java//JavaVirtualMachines/1.7.0.jdk/Contents/Home/include/jni.h ./
$ cp /Library/Java//JavaVirtualMachines/1.7.0.jdk/Contents/Home/include/darwin/jni_md.h ./

# install libsndfile, libsamplerate and mpg123 if not installed already
$ sudo port install libsndfile
$ sudo port install libsamplerate
$ sudo port install mpg123

# now run configure, with Java enabled as you likely want those cool bindings, and expect the missing libavcodec error:
$ ./configure --enable-java 


或者这会更有意义:

$ ./configure --enable-java CPPFLAGS="-I/opt/local/include" LDFLAGS="-L/opt/local/lib" 


但是 configure 完全忽略了新的 include/lib 路径 :( 似乎它们是在 configure 内部硬编码的。

...
checking CImg.h usability... no
checking CImg.h presence... no
checking for CImg.h... no
checking whether CImg.h is in the current or src directory.... yes

*** Configuring video Hash ***

checking whether FFmpeg is present... checking for avcodec_alloc_frame in -lavcodec... no
configure: error: 

*** libavcodec not found.



那么既然 configure 期望所有的库和包含在 /usr/local/ (而不是 /opt/local)中,我不能让它在别处寻找,唯一剩下要做的就是暴力破解它!:D

# edit ./configure as follows
$ nano configure
CTRL-W -> search for ' -L/' (note the space)

# edit the lines as follows
LDFLAGS="$LDFLAGS -L/usr/local/lib -L/opt/local/lib"
CPPFLAGS="$CPPFLAGS -I/usr/local/include -I/opt/local/include"  

# Or do the newbie version (I actually did this the first time!)
$ sudo mv /usr/local/lib /usr/local/lib-foo
$ sudo mv /usr/local/include/ /usr/local/include-foo
$ sudo ln -s /opt/local/lib /usr/local/lib
$ sudo ln -s /opt/local/include /usr/local/include

$ ll /usr/local/

total 16
drwxr-xr-x  32 root  wheel  1088 Jun 29 18:04 bin
drwxr-xr-x   3 root  wheel   102 Mar  6 14:40 etc
lrwxr-xr-x   1 root  wheel    18 Jul 12 19:27 include -> /opt/local/include
drwxr-xr-x  11 root  wheel   374 Jul 12 19:22 include-foo
lrwxr-xr-x   1 root  wheel    14 Jul 12 19:27 lib -> /opt/local/lib
drwxr-xr-x  25 root  wheel   850 Jul 12 19:23 lib-foo
drwxr-xr-x   8 root  wheel   272 Oct 11  2010 sbin
drwxr-xr-x   4 root  wheel   136 Jun 12 11:52 share

# at this point ./configure should work ok


是时候运行 make - 你会得到一堆错误:

$ make

# on to the code bits:
# we need to adjust src/cimgffmpeg.cpp to support the latest version of ffmpeg
# a few things have moved from being deprecated to having been completely changed:

$ make 2>&1 | grep error

cimgffmpeg.cpp:57: error: 'av_open_input_file' was not declared in this scope
cimgffmpeg.cpp:70: error: 'CODEC_TYPE_VIDEO' was not declared in this scope
cimgffmpeg.cpp:134: error: 'avcodec_decode_video' was not declared in this scope
cimgffmpeg.cpp:202: error: 'av_open_input_file' was not declared in this scope
cimgffmpeg.cpp:216: error: 'CODEC_TYPE_VIDEO' was not declared in this scope
cimgffmpeg.cpp:283: error: 'avcodec_decode_video' was not declared in this scope
cimgffmpeg.cpp:339: error: 'av_open_input_file' was not declared in this scope
cimgffmpeg.cpp:357: error: 'av_open_input_file' was not declared in this scope
cimgffmpeg.cpp:368: error: 'CODEC_TYPE_VIDEO' was not declared in this scope
cimgffmpeg.cpp:399: error: 'av_open_input_file' was not declared in this scope
cimgffmpeg.cpp:410: error: 'CODEC_TYPE_VIDEO' was not declared in this scope

# change as follows; left: original downloaded source, right: modified source 

$ diff ~/Downloads/pHash-0.9.4-fresh/src/cimgffmpeg.cpp ~/dev/pHash-0.9.4/src/cimgffmpeg.cpp

57c57
<       if(av_open_input_file(&st_info->pFormatCtx, st_info->filename, NULL, 0, NULL)!=0)
---
>       if(avformat_open_input(&st_info->pFormatCtx, st_info->filename, NULL, NULL)!=0)

70c70
<       if(st_info->pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO) 
---
>       if(st_info->pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) 

134c134
<         avcodec_decode_video(st_info->pCodecCtx, pFrame, &frameFinished,packet.data, packet.size);
---
>         avcodec_decode_video2(st_info->pCodecCtx, pFrame, &frameFinished, &packet);

202c202
<       if(av_open_input_file(&(st_info->pFormatCtx),st_info->filename,NULL,0,NULL)!=0){
---
>       if(avformat_open_input(&(st_info->pFormatCtx),st_info->filename,NULL,NULL)!=0){

216c216
<           if(st_info->pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO) 
---
>           if(st_info->pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) 

282,283c282
<           avcodec_decode_video(st_info->pCodecCtx, pFrame, &frameFinished,
<                                packet.data,packet.size);
---
>           avcodec_decode_video2(st_info->pCodecCtx, pFrame, &frameFinished, &packet);

339c338
<   if (av_open_input_file(&pFormatCtx, file, NULL, 0, NULL))
---
>   if (avformat_open_input(&pFormatCtx, file, NULL, NULL))

357c356
<   if (av_open_input_file(&pFormatCtx, file, NULL, 0, NULL))
---
>   if (avformat_open_input(&pFormatCtx, file, NULL, NULL))

368c367
<        if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO) 
---
>        if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) 

399c398
<   if (av_open_input_file(&pFormatCtx, filename, NULL, 0, NULL))
---
>   if (avformat_open_input(&pFormatCtx, filename, NULL, NULL))

410c409
<            if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO) 
---
>            if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) 


我敢肯定,这很有趣,不用担心我们快到了。

# make should now complete with only useless warnings
$ make
$ sudo make -n install

# if all went well you've not got pHash with Java bindings
# let's build the Java files and test it

$ cd ll bindings/java/org/phash/
$ javac *.java

# go back to the Java bindins root and run
$ cd ../..

# oh yeah.. if you actually DID rename the include/lib dirs previously then: 
$ sudo rm /usr/local/lib
$ sudo rm /usr/local/include
$ sudo mv /usr/local/include-foo/ /usr/local/include
$ sudo mv /usr/local/lib-foo/ /usr/local/lib

# drum roll..
$ java -Djava.library.path=/usr/local/lib org/phash/pHash -mh ~/Downloads/s01.jpg ~/Downloads/s02.jpg 
File 1: /Users/xxx/Downloads/s01.jpg
File 2: /Users/xxx/Downloads/s02.jpg
0.3159722222222222

# now go try out your image recognition app ideas ;)
于 2012-07-16T06:53:25.830 回答