ffmpeg には libavfilter ライブラリ経由で利用できる filter 機能があり、必要に応じて独自の filter を作成し追加することが可能です。 このエントリでは frei0r に独自filterを追加する方法について説明していきます。
ffmpeg filters には filter の一覧と指定方法の説明があります。
filter には以下の特徴があります。
- video と audio 用の filter があります
- フィルタは多段掛けが可能です
- 基本的にはinputで受けたデータを加工しoutputに流し込みます
- input を提供するフィルタ(ソースフィルタ)もあります
- output を持たないフィルタ(シンクフィルタ)もあります
ffmpeg -filters
で利用可能なフィルタの一覧を見ることができます- ffmpeg に標準添付されている filter と、frei0r のような外部filter(ダイナミックリンク経由で利用するfilter) があります
このエントリでは frei0r version 1.5.0, OpenCV version 3.2.0, automake, autoconf, libtool, cmake を使用します。必要に応じてインストールしてください。
brew install ffmpeg --with-frei0r
brew install opencv3
brew install automake
brew install libtool
brew install cmake
frei0r には C で書かれたfilter と C++ で書かれたfilter があり、OpenCV や dlib とリンクする場合は C++ で記述していきます。
README の末尾に C++ のスケルトンコードがありますが、あまり参考になりません。frei0r のコードを頑張って読み解く必要があります。
独自 filter を追加する前に、必要のない filter やディレクトリを削除しておきます(コンパイル時間も短縮できます)。
src/filter 以下から、CMake関連のファイルとglow, facebl0r, facedetect, nvdi を残します。また doc/ は不要なので削除します。
-
src/filter 以下からディレクトリを削除します。
- 削除後はこのようになります
▾ filter/ ▸ CMakeFiles/ ▸ facebl0r/ ▸ facedetect/ ▸ glow/ ▸ ndvi/ cmake_install.cmake CMakeLists.txt* Makefile
-
doc ディレクトリを削除し設定を削ります
- CMakeLists.txt を開き
add_subdirectory (doc)
の行を削除します - configure.ac を開き
AC_CONFIG_FILES([...])
からdoc/Makefile
を削除します
- CMakeLists.txt を開き
-
src/filter/CMakeLists.txt から不要なfilter名を削除します
- 削除後はこのようになります
if (${OpenCV_FOUND}) add_subdirectory (facebl0r) add_subdirectory (facedetect) endif (${OpenCV_FOUND}) add_subdirectory (glow) add_subdirectory (ndvi)
-
src/Makefile.am から不要な
*.la
と*_la_SOURCES
を削除します- 削除後はこのようになります
plugin_LTLIBRARIES = \ glow.la \ ndvi.la if HAVE_OPENCV plugin_LTLIBRARIES += facebl0r.la facebl0r_la_SOURCES = filter/facebl0r/facebl0r.cpp facebl0r_la_CFLAGS = @OPENCV_CFLAGS@ @CFLAGS@ facebl0r_la_LIBADD = @OPENCV_LIBS@ plugin_LTLIBRARIES += facedetect.la facedetect_la_SOURCES = filter/facedetect/facedetect.cpp facedetect_la_CFLAGS = @OPENCV_CFLAGS@ @CFLAGS@ facedetect_la_LIBADD = @OPENCV_LIBS@ endif # # FILTERS # glow_la_SOURCES = filter/glow/glow.c ndvi_la_SOURCES = filter/ndvi/ndvi.cpp filter/ndvi/gradientlut.hpp AM_CPPFLAGS = -I@top_srcdir@/include AM_CFLAGS = -I@top_srcdir@/include AM_LDFLAGS = -module -avoid-version -lm -export-dynamic AM_LIBTOOLFLAGS = --tag=disable-static plugindir = @libdir@/frei0r-1 install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) mkdir -p $(DESTDIR)/$(plugindir) list='$(plugin_LTLIBRARIES)'; \ for file in $$list; do \ sofile=`basename $$file .la`.so; \ $(INSTALL_PROGRAM) .libs/$$sofile $(DESTDIR)/$(plugindir); \ done uninstall-pluginLTLIBRARIES: list='$(plugin_LTLIBRARIES)'; \ for file in $$list; do \ sofile=`basename $$file .la`.so; \ rm -f $(DESTDIR)/$(plugindir)/$$sofile; \ done
不要な filter を削った状態で frei0r をビルドします。
autoreconf -v
またはautoheader
,aclocal
,automake
,autonconf
の一連のコマンドを実行し、最後に ./configure を実行します- libtool でエラーになる場合は Workaround( libtool not found error )を参照してください
autoreconf -v
# または autoheader && aclocal && libtool --ltdl --copy --force && automake --add-missing --copy && autoconf
./configure
./configure
が成功したら make します。
make
make install
./dylib.sh # mac のみ
make install を行うと、/usr/local/lib/frei0r-1 以下にビルドした filter (*.so) が設置されます。
▾ /usr/
▾ local/
▾ lib/
▾ frei0r-1/
facebl0r.so
facedetect.so
glow.so
ndvi.so
mac では以下のsh (./dylib.sh) を実行し、*.so を *.dylib にコピーします。
for file in /usr/local/lib/frei0r-1/*.so ; do
cp $file "${file%.*}.dylib"
done
ビルドした filter が機能するか実行してみましょう。
ffmpeg -i a.mp4 -pix_fmt yuv420p -vf frei0r=glow:20 b.mp4
glow は特別な設定が不要なfilterなため、ビルドするだけで実行が可能です。
では次に、追加の設定が必要なfilter(facebl0r, facedetect) を実行してみましょう。
ffmpeg -i a.mp4 -pix_fmt yuv420p -vf frei0r=facebl0r b.mp4
OpenCVの設定が不十分な場合はエラーが発生し変換に失敗します。対処法は後述(Workaround: OpenCV, classifier, XML)します。
ERROR in filter facebl0r, classifier cascade not found: /usr/share/opencv/haarcascades/haarcascade_frontalface_default.xml
NVDI と NVDI の追加差分 を見ると、 以下の4つのファイルを作成/更新すれば良い事がわかります。
- src/Makefile.am
- src/filter/CMakeLists.txt
- src/filter/{{FILTERNAME}}/CMakeLists.txt
- src/filter/{{FILTERNAME}}/{{FILTERNAME}}.cpp
glow は C で書かれていましたが、NVDI は C++ で書かれています。ここから先は NVDI を例に独自 filter を追加する手順を説明していきます。
src/Makefile.am の 適切な場所に nvdi.la を追加します。
plugin_LTLIBRARIES = \
:
multiply.la \
+ nvdi.la \
nervous.la \
:
nvdi_la_SOURCES を追加します。ビルド対象の ndvi.cpp と utility 的な役割を持ったコード gradientlut.hpp を追加しています
medians_la_SOURCES = filter/medians/medians.c filter/medians/ctmf.h filter/medians/small_medians.h
+ nvdi_la_SOURCES = filter/ndvi/ndvi.cpp filter/ndvi/gradientlut.hpp
nervous_la_SOURCES = filter/nervous/nervous.cpp
OpenCV や Cairo などの外部ライブラリに依存した機能を追加する場合は、以下のように if xxx の中に追加します。
- ndvi は CAIRO に依存しているため if HAVE_CAIRO の内側に記述します。
- HAVE_OPENCV や HAVE_CAIRO については後述します。
if HAVE_OPENCV
plugin_LTLIBRARIES += facebl0r.la
facebl0r_la_SOURCES = filter/facebl0r/facebl0r.cpp
facebl0r_la_CFLAGS = @OPENCV_CFLAGS@ @CFLAGS@
facebl0r_la_LIBADD = @OPENCV_LIBS@
endif
if HAVE_CAIRO
ndvi_la_CPPFLAGS = @CAIRO_CFLAGS@ @CPPFLAGS@ -DHAVE_CAIRO
ndvi_la_LIBADD = @CAIRO_LIBS@
endif
nvdi ディレクトリを作成し、cmake のビルド対象にします。
add_subdirectory (measure)
endif ()
+ add_subdirectory (ndvi)
add_subdirectory (nervous)
nvdi/CMakeLists.txt を追加します。
SOURCES 変数には ビルド対象の cpp や hpp を指定します。複数ある場合は列挙します。
TARGET 変数には ビルドターゲットを指定します。
nvdi は Cairo を使用するため、target_link_libraries
マクロで Cairo のパスを設定しています
set (SOURCES ndvi.cpp gradientlut.hpp)
set (TARGET ndvi)
if (Cairo_FOUND)
include_directories(${Cairo_INCLUDE_DIR})
set(LIBS ${LIBS} ${Cairo_LIBRARY})
endif (Cairo_FOUND)
if (MSVC)
set (SOURCES ${SOURCES} ${FREI0R_DEF})
endif (MSVC)
add_library (${TARGET} MODULE ${SOURCES})
set_target_properties (${TARGET} PROPERTIES PREFIX "")
target_link_libraries(ndvi ${LIBS}) # Cairo のパスを設定 http://blog.wagavulin.jp/entry/2011/11/27/222642
install (TARGETS ${TARGET} LIBRARY DESTINATION ${LIBDIR})
filter のコードを追加します。
まずは src/filter/ndvi/gradientlut.hpp を追加します。
- GRADIENTLUT_PRINT を有効にすると、debug print を行うようです。
#include <vector>
//#define GRADIENTLUT_PRINT // debug print
#ifdef GRADIENTLUT_PRINT
#include <cstdio>
#endif
class GradientLut {
public:
struct Color {
uint8_t r;
uint8_t g;
uint8_t b;
};
void setDepth(size_t depth);
void fillRange(double startPos, const Color& startColor,
double endPos, const Color& endColor);
const Color& operator[](double pos) const;
void print() const;
private:
std::vector<Color> lut;
};
void GradientLut::setDepth(size_t depth) {
lut.resize(depth);
}
void GradientLut::fillRange( double startPos, const GradientLut::Color& startColor,
double endPos, const GradientLut::Color& endColor ) {
unsigned int startIndex = (double)(lut.size() - 1) * startPos + 0.5;
unsigned int endIndex = (double)(lut.size() - 1) * endPos + 0.5;
unsigned int span = endIndex - startIndex;
if(span < 1) span = 1;
for(int i = 0; i <= span; i++) {
Color color;
double ratio = (double)i / (double)span;
color.r = startColor.r + ratio * ((double)endColor.r - (double)startColor.r);
color.g = startColor.g + ratio * ((double)endColor.g - (double)startColor.g);
color.b = startColor.b + ratio * ((double)endColor.b - (double)startColor.b);
lut[i + startIndex] = color;
}
}
const GradientLut::Color& GradientLut::operator[](double pos) const {
unsigned int size = lut.size();
unsigned int index = (double)size * pos;
if(index >= size) {
index = size - 1;
}
return lut[index];
};
// Debug print function.
void GradientLut::print() const {
#ifdef GRADIENTLUT_PRINT
printf("LUT:\tIndex\tRed\tGreen\tBlue\n");
for(int i = 0; i < lut.size(); i++) {
const Color& color = lut[i];
printf("\t%3d\t%02x\t%02x\t%02x\n", i, color.r, color.g, color.b);
}
#endif
}
src/filter/ndvi/ndvi.cpp を追加します。こちらが filter の本体です。
#ifdef HAVE_CAIRO
#include <cairo.h>
#endif
#include "frei0r.hpp"
#include "frei0r_math.h"
#include "gradientlut.hpp"
#include <string>
#include <stdlib.h>
// This filter calculates NDVI values from near-infrared + blue (infrablue) video.
// The NDVI values are mapped to a false color image.
static inline double N2P(double ndvi) {
// Convert NDVi value (-1 to 1) to position (0 to 1).
return (ndvi + 1.0) / 2.0;
}
class Ndvi : public frei0r::filter {
public:
Ndvi(unsigned int width, unsigned int height);
virtual void update();
private:
void initLut();
double paramLutLevels;
std::string paramColorMap;
double paramVisScale;
double paramVisOffset;
double paramNirScale;
double paramNirOffset;
unsigned int lutLevels;
std::string colorMap;
GradientLut gradient;
};
Ndvi::Ndvi(unsigned int width, unsigned int height)
: paramLutLevels(256.0 / 1000.0)
, paramColorMap("grayscale")
, paramVisScale(0.1)
, paramVisOffset(0.5)
, paramNirScale(0.1)
, paramNirOffset(0.5)
, lutLevels(0)
, colorMap("")
, gradient() {
register_param(paramColorMap, "Color Map", "The color map to use. One of 'earth', 'grayscale', 'heat' or 'rainbow'.");
register_param(paramLutLevels, "Levels", "The number of color levels to use in the false image (divided by 1000).");
register_param(paramVisScale, "VIS Scale", "A scaling factor to be applied to the visible component (divided by 10).");
register_param(paramVisOffset, "VIS Offset", "An offset to be applied to the visible component (mapped to [-100%, 100%].");
register_param(paramNirScale, "NIR Scale", "A scaling factor to be applied to the near-infrared component (divided by 10).");
register_param(paramNirOffset, "NIR Offset", "An offset to be applied to the near-infrared component (mapped to [-100%, 100%].");
}
void Ndvi::update() {
uint8_t *inP = (uint8_t*)in;
uint8_t *outP = (uint8_t*)out;
double visScale = paramVisScale * 10.0;
double visOffset = (paramVisOffset * 510) - 255;
double nirScale = paramNirScale * 10.0;
double nirOffset = (paramNirOffset * 510) - 255;
initLut();
for (int i = 0; i < size; i++) {
double vis = inP[2]; // blue channel
double nir = inP[0]; // red channel
vis = (vis + visOffset) * visScale;
vis = CLAMP(vis, 0.0, 255.0);
nir = (nir + nirOffset) * nirScale;
nir = CLAMP(nir, 0.0, 255.0);
double ndvi = (nir -vis) / (nir + vis);
double pos = N2P(ndvi);
const GradientLut::Color& falseColor = gradient[pos];
outP[0] = falseColor.r;
outP[1] = falseColor.g;
outP[2] = falseColor.b;
outP[3] = 0xff;
inP += 4;
outP += 4;
}
}
void Ndvi::initLut() {
// Only update the LUT if a parameter has changed.
unsigned int paramLutLevelsInt = paramLutLevels * 1000.0 + 0.5;
if (lutLevels == paramLutLevelsInt &&
colorMap == paramColorMap) {
return;
} else {
lutLevels = paramLutLevelsInt;
colorMap = paramColorMap;
}
gradient.setDepth(lutLevels);
if(colorMap == "earth") {
...
} else if(colorMap == "heat") {
...
} else if(colorMap == "rainbow") {
...
} else { // grayscale
...
}
}
frei0r::construct<Ndvi> plugin("NDVI filter", // Filter short name
"This filter creates a NDVI false image from an infrablue source.", // description
"Brian Matherly", // Author
0, // Major version
1, // Minor version
F0R_COLOR_MODEL_RGBA8888); // in に渡されるカラーフォーマットの指定, 32bit RGBA
facebl0r はカラーフォーマットの指定が F0R_COLOR_MODEL_PACKED32 になっています。
frei0r::construct<FaceBl0r> plugin("FaceBl0r",
"automatic face blur",
"ZioKernel, Biilly, Jilt, Jaromil, ddennedy",
1,
1,
F0R_COLOR_MODEL_PACKED32); // PACKED32 は RGBA と BGRA の両方を内包できる 32bit型。OpenCVと受け渡しをする場合などに具体的な型の指定を避ける場合に使用します
via https://github.com/dyne/frei0r/commit/9fff22cc0dff61945ce04ecc835b507cdf3547e6
独自 filter を追加する場合も、nvdi の例にならって追加していきます。
さていよいよ本題です。OpenCV と dlib を使った独自 filter を追加していきます。ここで追加する filter の名前は facedlib とします。
まずは、facedetect をコピーした facedlib を作成し、dlib の ヘッダを組み込んでみます(ヘッダは組み込みますが、dlib はまだ呼び出しません)。
-
configure.ac に以下の行を追加し DLIB_CPPFLAGS 変数を定義します
# Checks for programs. AC_PROG_CXX AC_PROG_CC AC_PROG_CC_C99 LT_INIT([disable-static]) + DLIB_CPPFLAGS="-std=c++11 -stdlib=libc++" + AC_SUBST(DLIB_CPPFLAGS)
-
src/filter/facedlib/ を作成します
-
src/filter/facedlib/dlib に dlib/dlib をコピーして設置します
▾ facedlib/ ▾ dlib/ ▾ all/ source.cpp ▸ any/
-
src/filter/CMakeLists.txt に facedlib を追加します
if (${OpenCV_FOUND}) add_subdirectory (facebl0r) add_subdirectory (facedetect) + add_subdirectory (facedlib) endif (${OpenCV_FOUND}) add_subdirectory (glow) add_subdirectory (ndvi)
-
src/filter/facedlib/CMakeLists.txt を作成します
set (SOURCES facedlib.cpp) set (TARGET facedlib) if (MSVC) set (SOURCES ${SOURCES} ${FREI0R_DEF}) endif (MSVC) include_directories(./src/filter/facedlib/dlib) # [!] set(LIBS ${LIBS} ./src/filter/facedlib/dlib) # [!] include_directories (${OpenCV_INCLUDE_DIR}) link_directories (${OpenCV_LIBRARY_DIRS}) LINK_LIBRARIES(${OpenCV_LIBS} ${OpenCV_LIBRARIES}) add_library (${TARGET} MODULE ${SOURCES}) set_target_properties (${TARGET} PROPERTIES PREFIX "") target_link_libraries(facedlib ${LIBS}) # [!] install (TARGETS ${TARGET} LIBRARY DESTINATION ${LIBDIR})
-
src/filter/facedlib/facedlib.cpp を作成します。
- 内容は、facedetect/facedetect.cpp をコピーし
FaceDetect
をFaceDlib
に変換します
- 内容は、facedetect/facedetect.cpp をコピーし
-
src/Makefile.am に facedlib の情報を追加します
- dlib/all/source.cpp を組み込みます -congigure.ac で追加した DLIB_CPPFLAGS をここで使用します
if HAVE_OPENCV plugin_LTLIBRARIES += facebl0r.la facebl0r_la_SOURCES = filter/facebl0r/facebl0r.cpp facebl0r_la_CFLAGS = @OPENCV_CFLAGS@ @CFLAGS@ facebl0r_la_LIBADD = @OPENCV_LIBS@ plugin_LTLIBRARIES += facedetect.la facedetect_la_SOURCES = filter/facedetect/facedetect.cpp facedetect_la_CFLAGS = @OPENCV_CFLAGS@ @CFLAGS@ facedetect_la_LIBADD = @OPENCV_LIBS@ + plugin_LTLIBRARIES += facedlib.la + facedlib_la_SOURCES = filter/facedlib/facedlib.cpp filter/facedlib/dlib/all/source.cpp + facedlib_la_CFLAGS = @OPENCV_CFLAGS@ @CFLAGS@ @DLIB_CPPFLAGS@ + facedlib_la_LIBADD = @OPENCV_LIBS@ endif
この段階で一度以下のコマンドを実行しビルドを行います。
autoreconf -v
./configure
make clean
make
error: "Dlib requires C++11 support. Give your compiler the -std=c++11 option to enable it."
とエラーが発生するため、
src/Makefile を編集し、ビルドフラグ(-std=c++11 -stdlib=libc++
)を直接指定します。なお src/Makefile は ./configure で自動生成されるファイルなため ./configure 後は再度この作業を行ってください。
(facedlib.lo と source.lo に対して DLIB_CPPFLAGS の設定を適用する方法が不明なため、このようにしています)
facedlib.lo: filter/facedlib/facedlib.cpp
$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile \
$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT facedlib.lo -MD -MP -MF $(DEPDIR)/facedlib.Tpo -c -o facedlib.lo `test -f 'filter/facedlib/facedlib.cpp' || echo '$(srcdir)/'`filter/facedlib/facedlib.cpp
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -std=c++11 -stdlib=libc++ -MT facedlib.lo -MD -MP -MF $(DEPDIR)/facedlib.Tpo -c -o facedlib.lo `test -f 'filter/facedlib/facedlib.cpp' || echo '$(srcdir)/'`filter/facedlib/facedlib.cpp
$(AM_V_at)$(am__mv) $(DEPDIR)/facedlib.Tpo $(DEPDIR)/facedlib.Plo
# $(AM_V_CXX)source='filter/facedlib/facedlib.cpp' object='facedlib.lo' libtool=yes \
# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
# $(AM_V_CXX_no)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o facedlib.lo `test -f 'filter/facedlib/facedlib.cpp' || echo '$(srcdir)/'`filter/facedlib/facedlib.cpp
source.lo: filter/facedlib/dlib/all/source.cpp
$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile \
$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT source.lo -MD -MP -MF $(DEPDIR)/source.Tpo -c -o source.lo `test -f 'filter/facedlib/dlib/all/source.cpp' || echo '$(srcdir)/'`filter/facedlib/dlib/all/source.cpp
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -std=c++11 -stdlib=libc++ -MT source.lo -MD -MP -MF $(DEPDIR)/source.Tpo -c -o source.lo `test -f 'filter/facedlib/dlib/all/source.cpp' || echo '$(srcdir)/'`filter/facedlib/dlib/all/source.cpp
$(AM_V_at)$(am__mv) $(DEPDIR)/source.Tpo $(DEPDIR)/source.Plo
# $(AM_V_CXX)source='filter/facedlib/dlib/all/source.cpp' object='source.lo' libtool=yes \
# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \
# $(AM_V_CXX_no)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o source.lo `test -f 'filter/facedlib/dlib/all/source.cpp' || echo '$(srcdir)/'`filter/facedlib/dlib/all/source.cpp
src/Makefile を更新したら ./configure を行わずに、make clean, make を行ってください。
make clean
make
-
frei0r が Cario を使った filter を初めてサポートした時の diff がこちら
-
Add new cairo plugins to the autotools build.
# HAVE_CAIRO 変数には FALSE または TRUE が設定されます HAVE_CAIRO=false PKG_CHECK_MODULES(CAIRO, cairo >= 1.0.0, [HAVE_CAIRO=true], [true]) AM_CONDITIONAL([HAVE_CAIRO], [test x$HAVE_CAIRO = xtrue])
-
Mac で clang を使用するようにビルドオプションを変更した時の diff がこちら
-
facedetect が c から cpp で書き直されたときの diff がこちら
-
AM_CONDITIONAL マクロについては http://nantonaku-shiawase.hatenablog.com/entry/2015/01/08/005544 を参照してください。
-
AX_CXX_COMPILE_STDCXX_11 マクロを使うと自動的に C++11のフラグをよしなにしてくれるらしい → してくれませんでした。
-
https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html から ax_cxx_compile_stdcxx_11.m4 をダウンロードし、m4/ax_cxx_compile_stdcxx_11.m4 として設置し、以下を configure.ac に追加すると良いらしい
# Checks for programs. AC_PROG_CXX AC_PROG_CC AC_PROG_CC_C99 LT_INIT([disable-static]) + m4_include([m4/ax_cxx_compile_stdcxx_11.m4]) + AX_CXX_COMPILE_STDCXX_11 + AC_LANG([C++])
-
-
frei0r version 1.5 では opencv3 が必要です。以下のエラーがでる場合は opencv1 or 2 をアンインストールし、opencv3 をインストールし直してください(frei0r version 1.4 は opencv2 が必要です)
-
brew uninstall opencv && brew install opencv3 && brew link opencv3 --force
Scanning dependencies of target facedetect [ 1%] Building CXX object src/filter/facedetect/CMakeFiles/facedetect.dir/facedetect.cpp.o [ 2%] Linking CXX shared module facedetect.so ld: warning: ignoring file /usr/local/Cellar/opencv/2.4.13.2/lib/libopencv_calib3d.dylib, file was built for x86_64 which is not the architecture being linked (i386): /usr/local/Cellar/opencv/2.4.13.2/lib/libopencv_calib3d.dylib Undefined symbols for architecture i386:
-
-
AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION) で warn がでる場合は
- https://www.gnu.org/software/automake/manual/automake.html#Modernize-AM_005fINIT_005fAUTOMAKE-invocation を参考に configure.ac を修正します
- AC_INIT(frei0r-plugins, [1.5.0], [frei0r-devel@piksel.no]) - AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION) + AC_INIT([frei0r-plugins], [1.5.0]) + AM_INIT_AUTOMAKE
-
dylib.sh
- mac では *.so ではなく *.dylib が必要なため以下のスクリプトを実行する必要があります。
- 以下のコマンドを ./dylib.sh として作成し、
chmod +x dylib.sh
として実行権限を付与し、make install
後に./dylib.sh
を実行すると良いでしょう。
When using Apple/OSX, the dlopen() mechanism (in FFMpeg for instance) will look for .dylib extensions and not the .so that frei0r plugins have by default. To fix this problem one can rename the plugins simply so:
for file in /usr/local/lib/frei0r-1/*.so ; do cp $file "${file%.*}.dylib" done
-
OpenCVの設定が不十分だと
ERROR in filter facebl0r, classifier cascade not found
エラーが発生します これに対処するには OpenCV で読み込む classifier (XML) の更新とパスを修正する必要がありますERROR in filter facebl0r, classifier cascade not found: /usr/share/opencv/haarcascades/haarcascade_frontalface_default.xml
-
OpenCV の classifier (XML) を更新する
-
src/filter/facebl0r/facebl0r.cpp が参照している classifier XML は古く、またパスも修正する必要があります
/usr/
以下は、El Capitan 以降でファイル設置不能ですbrew install opencv3
でインストールされる xml ファイルのフォーマットが古い場合があります- 最新版のXML(haarcascade_frontalface_default.xml)を https://ja.osdn.net/projects/sfnet_magicvisionport/downloads/mvp/cascades/haarcascade_frontalface_default.xml/ からダウンロードします
- /usr/local/Cellar/opencv/{{version}}/share/OpenCV/haarcascades/haarcascade_frontalface_default_new.xml として設置します
- opencv のインストールパスは、
brew link opencv3
で取得できます- 例:
/usr/local/Cellar/opencv3/3.2.0
- 例:
- xml ファイルパスを src/filter/facebl0r/facebl0r.cpp と src/filter/facedetect/facedetect.cpp に直接指定します
- classifier = "/usr/share/opencv/haarcascades/haarcascade_frontalface_default.xml"; + classifier = "/usr/local/Cellar/opencv3/3.2.0/share/OpenCV/haarcascades/haarcascade_frontalface_default_new.xml";
-
-
frei0r version 1.4.0 についてはこちらを参照してください
-
libtool not found error
- 一部の環境では libtool ではなく glibtoolize という名前で存在する場合があります
/usr/local/lib/pkgconfig/frei0r.pc
これ以外の事でやり方がわからない場合は master ブランチのコミットログを追いかけましょう