在 OSX 上构建 pHash 0.9.4 可能会很棘手。对于那些遇到问题的人,我在下面的冗长回答可能会有所帮助。
问问题
2829 次
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 回答