如何在MacOSX Lion上构建pHash(使用最新的ffmpeg-devel)



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


确保您的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希望所有的libs和include都在/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 ;)

最新更新