The article is based on How to use the OpenCV parallel_for_ to parallelize your code, the example project uses OpenCV parallel_for_
to speed up the computing process.
Now I plan to use the algorithm class vtkSMPTools in VTK to get the same positive effect.
The unit computing task is put in operator()
of ParallelWorker.
If you didn’t configure the VTK SMP implementation type to parallelize way, I wish the article Configure TBB – VTK Environment For Mac can help you.
class ParallelWorker
{
public:
ParallelWorker( Mat *mandelbrotImg, float scaleX, float scaleY, float x1, float y1 )
{
m_MandelbrotImg = mandelbrotImg;
m_ScaleX = scaleX;
m_ScaleY = scaleY;
m_X1 = x1;
m_Y1 = y1;
}
~ParallelWorker(){ m_MandelbrotImg = nullptr; }
void operator()(vtkIdType begin, vtkIdType end)
{
for ( vtkIdType index = begin; index < end; ++index )
{
int i = index / m_MandelbrotImg->cols;
int j = index % m_MandelbrotImg->cols;
float x0 = j / m_ScaleX + m_X1;
float y0 = i /m_ScaleY + m_Y1;
complex<float> z0(x0, y0);
uchar value = (uchar) mandelbrotFormula(z0);
m_MandelbrotImg->ptr<uchar>(i)[j] = value;
}
}
protected:
Mat *m_MandelbrotImg;
float m_ScaleX;
float m_ScaleY;
float m_X1;
float m_Y1;
};
int main()
{
Mat mandelbrotImg(480, 540, CV_8U);
//...
double t1 = (double) getTickCount();
ParallelWorker worker( &mandelbrotImg, scaleX, scaleY, x1, y1 );
vtkSMPTools::For(0, mandelbrotImg.rows*mandelbrotImg.cols, worker );
t1 = ((double) getTickCount() - t1) / getTickFrequency();
cout << "Parallel Mandelbrot: " << t1 << " s" << endl;
Mat mandelbrotImgSequential(480, 540, CV_8U);
double t2 = (double) getTickCount();
sequentialMandelbrot(mandelbrotImgSequential, x1, y1, scaleX, scaleY);
t2 = ((double) getTickCount() - t2) / getTickFrequency();
cout << "Sequential Mandelbrot: " << t2 << " s" << endl;
cout << "Speed-up: " << t2/t1 << " X" << endl;
//...
Output:
Parallel Mandelbrot: 0.0861828 s
Sequential Mandelbrot: 0.241033 s
Speed-up: 2.79677 X
Here is CMakeLists.txt for import libraries VTK and OpenCV.
macro(use_cxx11)
if (CMAKE_VERSION VERSION_LESS "3.1")
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
endif ()
else ()
set (CMAKE_CXX_STANDARD 11)
endif ()
endmacro(use_cxx11)
cmake_minimum_required(VERSION 2.8)
project( OpenCV_Parallel )
use_cxx11()
find_package( OpenCV REQUIRED )
find_package( VTK REQUIRED )
include( ${VTK_USE_FILE} )
add_executable( ${PROJECT_NAME} MACOSX_BUNDLE "main.cpp" )
target_link_libraries( ${PROJECT_NAME} ${OpenCV_LIBS} ${VTK_LIBRARIES})