Posted on 11-08-2016
Filed Under (Technology) by bigbang

The library versions using in this article: OpenCV2.4.13, FFMpeg 2.8.7, CMake 3.5.

First of all, you need to install FFMpeg on Mac OSX first. The step is very easy just like doing it on other Unix/Linux platform.

Then download OpenCV 2.4.13 and unzip it to a folder. Enter this folder from terminal and here are basic steps for OpenCV 2.4.13 compilation under Mac:

mkdir build
cd build
cmake -G "Unix Makefiles" ..
make -j8
sudo make install

According to OpenCV version and FFMpeg dependency, you might meet some compilation errors.

Error 1: not generating corresponding makefile

Here is an example error message:

In file included from /Users/collins/Documents/temp/opencv-2.4.13/3rdparty/zlib/zlib.h:34:

/Users/collins/Documents/temp/opencv-2.4.13/release/3rdparty/zlib/zconf.h:426:14: fatal error:

      'sys/types.h' file not found

#    include <sys/types.h>      /* for off_t */

	     ^
1 error generated.

Try to generate correct makefile on Mac, you should use following parameters in cmake command:

cmake -G "Unix Makefiles" ..

So your final OpenCV project generating cmake parameters should be something like this:

cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -G "Unix Makefiles" ..

Error 2: link CoreMedia, VideoToolBox frameworks or something else on Mac

An example error message is as following:

[ 33%] Building CXX object modules/highgui/CMakeFiles/opencv_highgui.dir/src/bitstrm.cpp.o

[ 33%] Linking CXX shared library ../../lib/libopencv_highgui.dylib

Undefined symbols for architecture x86_64:

  "_CMBlockBufferCreateWithMemoryBlock", referenced from:

      _videotoolbox_common_end_frame in libavcodec.a(videotoolbox.o)

  "_CMSampleBufferCreate", referenced from:

      _videotoolbox_common_end_frame in libavcodec.a(videotoolbox.o)

  "_CMVideoFormatDescriptionCreate", referenced from:

      _av_videotoolbox_default_init2 in libavcodec.a(videotoolbox.o)

  "_SSLClose", referenced from:

      _tls_open in libavformat.a(tls_securetransport.o)

      _tls_close in libavformat.a(tls_securetransport.o)
  "_SSLCopyPeerTrust", referenced from:

The reason of above error message is that some FFMpeg version under Mac is depended on VideoToolBox & CoreMedia Frameworks.

The solution is to modify and add following code into opencv-x.x.x/modules/highgui/CMakeLists.txt file:

find_library(CORE_MEDIA CoreMedia)
if (NOT CORE_MEDIA)
    message(FATAL_ERROR "CoreMedia not found")
endif()

find_library(VIDEO_TOOL_BOX VideoToolBox)
if (NOT VIDEO_TOOL_BOX)
    message(FATAL_ERROR "VideoToolBox not found")
endif()

find_library(SECURITY Security)
if (NOT SECURITY)
    message(FATAL_ERROR "Security not found")
endif()

target_link_libraries(${the_module} ${CORE_MEDIA} ${VIDEO_TOOL_BOX} ${SECURITY})

So at the compilation time, it will link VideoToolBox, CoreMedia, Security frameworks under System/Library/Frameworks folder.

Another solution is not to compile highgui library, you can do this such kind of thing like this:

cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D BUILD_opencv_highgui=OFF -G "Unix Makefiles" ..

Adding CoreMedia & VideoToolBox libraries is not enough, You might still get following errors:

ld: warning: directory not found for option '-L/usr/local/lib/Debug'
ld: warning: directory not found for option '-L/usr/local/Cellar/x264/r2601/lib/Debug'
ld: warning: directory not found for option '-L/usr/local/Cellar/libvpx/1.5.0/lib/Debug'
ld: warning: directory not found for option '-L/usr/local/Cellar/opus/1.1.1/lib/Debug'
ld: warning: directory not found for option '-L/usr/local/Cellar/freetype/2.6_1/lib/Debug'
ld: warning: directory not found for option '-L/usr/local/Cellar/fdk-aac/0.1.4/lib/Debug'
ld: warning: directory not found for option '-L/usr/local/Cellar/libass/0.13.1/lib/Debug'
Undefined symbols for architecture x86_64:
  "_SSLClose", referenced from:
      _tls_open in libavformat.a(tls_securetransport.o)
      _tls_close in libavformat.a(tls_securetransport.o)
  "_SSLCopyPeerTrust", referenced from:
      _tls_open in libavformat.a(tls_securetransport.o)
  "_SSLCreateContext", referenced from:
      _tls_open in libavformat.a(tls_securetransport.o)
  "_SSLHandshake", referenced from:
      _tls_open in libavformat.a(tls_securetransport.o)
  "_SSLRead", referenced from:
      _tls_read in libavformat.a(tls_securetransport.o)
  "_SSLSetCertificate", referenced from:

That’s the reason why I need to add security.framework to CMakeLists.txt file.

According to different OpenCV & FFMpeg version, you might try to link other frameworks this way by your self to make sure you can install OpenCV successfully.

(0) Comments    Read More   
Posted on 11-08-2016
Filed Under (Technology) by bigbang

While writing program on Mac, sometimes we need to link framework and libraries under OSX folder System/Library/Frameworks. There are so many frameworks like CoreMedia & VideoToolBox, which you will use in FFMpeg or something else someday.

In this situation, we have to use find_library as it includes some special handling for frameworks on OSX.

Also, don’t use link_directories, CMake use full paths to libraries and it’s not needed.

Here’s some simple example with CoreMedia:

find_library(CORE_MEDIA CoreMedia)
if (NOT CORE_MEDIA)
    message(FATAL_ERROR "CoreMedia not found")
endif()

add_executable(program ${program_SOURCES})
target_link_libraries(program ${CORE_MEDIA})
(0) Comments    Read More   
Posted on 06-01-2016
Filed Under (Technology) by bigbang

We can build OpenCV under Visual Studio by using CMake under Windows7. It is very easy to do this job using edition OpenCV 2.4.X with Visual Studio 2008.

But when I try to build OpenCV 3.1.0 under Visual Studio 2008, there are some errors!

The first error is :

Error   131     fatal error C1083: Cannot open include file: 'stdint.h': No such file or directory      g:\setup_files\opencv\windows\opencv-3.1.0\sources\modules\imgcodecs\src\jpeg_exif.hpp  51

To fix this error, just google the stdint.h file and put it under the build path of OpenCV.

The second error is:

Error   1       error C2039: 'data' : is not a member of 'std::vector<_Ty>'     g:\setup_files\OpenCV\Windows\OpenCV-3.1.0\sources\modules\videoio\src\cap_mjpeg_decoder.cpp    793

This error is generated by \modules\videoio\src∩_mjpeg_decoder.cpp line 793, the origin code is:

m_file_stream.read(result.data(), chunk.m_size);

To fix this error, just change the code into following:

m_file_stream.read(&result[0], chunk.m_size);

OpenCV 3.1.0 uses C++11 code but Visual Studio 2008 doesn’t support this feature.

By done these, re-compile your solution then you will get the OpenCV 3.1.0 libraries from Visual Studio 2008.

(0) Comments    Read More   
Posted on 25-10-2013
Filed Under (Technology) by bigbang

QtService is a library not maintained by Qt right now, but a lot of engineers find that it is useful when you want to write a Windows application with Windows Service.

First, git clone the code from

git://gitorious.org/qt-solutions/qt-solutions.git

After checkout, there is a folder qtservice which is the target in this post. Enter the folder and we will compile the library for later usage.

Second, compile the code into a library under Windows. Use Qt Command Prompt, jump to the source folder and use following commands to compile it:

configure.bat

qmake

nmake.exe

The nmake.exe is the Visual Studio compiler, you can find it under Visual Studio installation path.

If the command prompt provides you with an error code:

NMAKE : fatal error U1077: 'cl' : return code '0x1'
Stop.
NMAKE : fatal error U1077: '"C:\Program Files\Microsoft Visual Studio 9.0\VC\bin
\nmake.exe"' : return code '0x2'
Stop.
NMAKE : fatal error U1077: 'cd' : return code '0x2'
Stop.

The reason is that you don’t use Qt Command Prompt.

After Compiled the code successfully, you can copy qtservice.h and generated library files such as QtSolutions_Service-head.dll, QtSolutions_Service-head.lib to your project folder. You link them in your pro file, then you can write QtService code. Just read examples under doc folder, and you will find the way.

If you use QtService in your application which name is example.exe for example, you can use following command to check the usage:

example.exe -help

and you can use following command to run the application as normal command line tool:

example.exe -exec
(0) Comments    Read More   
Posted on 02-10-2013
Filed Under (Technology) by bigbang

I tried to write a simple http server using Qt as a desktop tool. But when I tried to handle Chinese characters in UTF-8 encoding, my Firefox will always get mess characters.

The reason must be the difference between QString encoding and http encoding. I have encoded the http content using UTF-8, and I also should do something for QString.

Finally, I find the steps to let this simple http server handle Chinese characters.

First, in main function of your program, using following code to set global QString handler:

QTextCodec *codec = QTextCodec::codecForLocale();
QTextCodec::setCodecForTr(codec);

Second, when you get http request, process the request and generate the feedback of the http request, you can send the content by following code using UTF-8:

//generate html content according to http request
//which is result
...
QString content = tr("HTTP/1.0 200 Ok\r\n"
                                "Content-Type: text/html; charset=\"utf-8\"\r\n"
                                "\r\n");
content = content + result;

QTcpSocket* socket = (QTcpSocket*)sender();
QTextStream os(socket);
os.setCodec("UTF-8");
os.setAutoDetectUnicode(true);
os << content;

Then you will get the right output in you web browser.

(0) Comments    Read More   
Posted on 07-09-2013
Filed Under (Technology) by bigbang
  1. Fasest way: shared memory

    If you need fast IPC between two processes on one machine, you should look into whatever form of shared memory the platform offers. A simple protocol based around shared memory and locks or semaphores is by far the fastest technique.

  2. Socket

    If you do decide to use sockets, bind the “server” socket to ‘localhost’. On most platforms, this will take a shortcut around a couple of layers of network code and be quite a bit faster.

(0) Comments    Read More   
Posted on 07-09-2013
Filed Under (Technology) by bigbang

I am building my application using MFC Dialog application framework. I have printed logs in my output window by using TRACE. Now I want to print my logs on my Dialog, for example, in an Edit box or list box.

If we can transport the logs printed by TRACE into this control on my Dialog, it will be wonderful!

The list box is best for this. Make sure you turn off its ‘Sort’ property so the strings will be displayed in the order you add them. Call the list box AddString to add each line.

(0) Comments    Read More   
Posted on 16-06-2013
Filed Under (Technology) by bigbang

It seems that Boost Log is a good choice for cross platform logging. However, boost log is not part of Boost, at least not in the regular Boost branch. If you want to use this in you code, just follow the steps.

  1. Download Boost Log separately from here.
  2. Download Boost above version 1.51. I am using Boost version 1.53.0.
  3. Unzip the Boost source file, and unzip Boost Log file into the specific folder.
  4. Then compile the Boost file by Boost instruction. After the compilation, the Boost Log library will be under folder /boost_1_53_0/stage/lib or the installation folder you prefixed.

Then you can use the static Boost Log library in your code. Here is the example code:

#include <boost/log/trivial.hpp>

int main(int, char*[])
{
    BOOST_LOG_TRIVIAL(trace) << "A trace severity message";
    BOOST_LOG_TRIVIAL(debug) << "A debug severity message";
    BOOST_LOG_TRIVIAL(info) << "An informational severity message";
    BOOST_LOG_TRIVIAL(warning) << "A warning severity message";
    BOOST_LOG_TRIVIAL(error) << "An error severity message";
    BOOST_LOG_TRIVIAL(fatal) << "A fatal severity message";

    return 0;
}
(0) Comments    Read More   
Posted on 13-03-2013
Filed Under (Technology) by bigbang

The extern keyword in C & C++ is a little complex, by studying from Using extern to Specify Linkage, save it for notes.

The extern keyword declares a variable or function and specifies that it has external linkage (its name is visible from files other than the one in which it’s defined). When modifying a variable, extern specifies that the variable has static duration (it is allocated when the program begins and deallocated when the program ends). The variable or function may be defined in another source file, or later in the same file. Declarations of variables and functions at file scope are external by default.

// specifying_linkage1.cpp
int i = 1;
void other();

int main() {
   // Reference to i, defined above:
   extern int i;
}

void other() {
   // Address of global i assigned to pointer variable:
   static int *external_i = &i;

   // i will be redefined; global i no longer visible:
   // int i = 16;
}

In C++, when used with a string, extern specifies that the linkage conventions of another language are being used for the declarator(s). C functions and data can be accessed only if they are previously declared as having C linkage. However, they must be defined in a separately compiled translation unit.

Microsoft C++ supports the strings “C” and “C++” in the string-literal field. All of the standard include files use the extern “C” syntax to allow the run-time library functions to be used in C++ programs.

The following example shows alternative ways to declare names that have C linkage:

// specifying_linkage2.cpp
// compile with: /c
// Declare printf with C linkage.
extern "C" int printf( const char *fmt, ... );

//  Cause everything in the specified header files
//   to have C linkage.
extern "C" {
   // add your #include statements here
   #include <stdio.h>
}

//  Declare the two functions ShowChar and GetChar
//   with C linkage.
extern "C" {
   char ShowChar( char ch );
   char GetChar( void );
}

//  Define the two functions ShowChar and GetChar
//   with C linkage.
extern "C" char ShowChar( char ch ) {
   putchar( ch );
   return ch;
}

extern "C" char GetChar( void ) {
   char ch;

   ch = getchar();
   return ch;
}

// Declare a global variable, errno, with C linkage.
extern "C" int errno;
(0) Comments    Read More   
Posted on 07-03-2013
Filed Under (Technology) by bigbang

Using FFmpeg under Windows, especially using Visual C++, is not very well supported or documented. Today I tried this and mark this down for reference.

1. Download pre-compiled builds or compile from source

The first thing is to download the latest “Shared” and “Dev” builds from Zeranoe FFmpeg builds.

At the time of this writing, the “Dev” builds contain the headers and libs, but not the dlls, so use the “bin” folder of the “Shared” zip.

Note it’s possible to compile FFmpeg (which contains libavcodec) on Windows with MinGW & MSYS, but not with Visual Studio. If you are interesting about compiling FFmpeg on Windows, please check this post.

2. Using libavcodec in Visual Studio

Now configure your project to use the libs, headers and dlls. For the includes, you need to add:

[ffmpeg_directory]\include

Add the corresponding libs under linker options as usual.

[Your_ffmpeg_directory]\lib

3. add missing inttypes.h & stdint.h header file

Even just using libavcodec’s headers requires inttypes.h & stdint.h, and Visual Studio 9/10 doesn’t have it. Download this version and put in your FFmpeg include folder.

[ffmpeg_directory]\include

The most important thing is to add __STDC_CONSTANT_MACROS to Preprocessor, or add following code directly in source file:

#define __STDC_CONSTANT_MACROS

4. Test Code

Since libavcodec is a C library, we have to enclose the #includes in an extern C block. If following code works OK, then you can write more complicated application.

extern "C" {
    #include <libavcodec/avcodec.h>
    #include <libavformat/avformat.h>
    #include <libswscale/swscale.h>
}

int main( int argc, char* argv[] ) {
    av_register_all();
    return 0;
}

If you want to try more examples, there are a few examples under folder:

[ffmpeg_directory]\doc\examples

It is not complex but just steps!

(4) Comments    Read More