. Parallel_for_()函数parallelize代码

#include

#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>

using namespace std;
using namespace cv;

namespace
{
//! [mandelbrot-escape-time-algorithm]
int mandelbrot(const complex &z0, const int max)
{
complex z = z0;
for (int t = 0; t < max; t++)
{
if (z.real()*z.real() + z.imag()z.imag() > 4.0f) return t;
z = z
z + z0;
}

return max;

}
//! [mandelbrot-escape-time-algorithm]

//! [mandelbrot-grayscale-value]
int mandelbrotFormula(const complex &z0, const int maxIter=500) {
int value = mandelbrot(z0, maxIter);
if(maxIter - value == 0)
{
return 0;
}

return cvRound(sqrt(value / (float) maxIter) * 255);

}
//! [mandelbrot-grayscale-value]

//! [mandelbrot-parallel]
class ParallelMandelbrot : public ParallelLoopBody
{
public:
ParallelMandelbrot (Mat &img, const float x1, const float y1, const float scaleX, const float scaleY)
: m_img(img), m_x1(x1), m_y1(y1), m_scaleX(scaleX), m_scaleY(scaleY)
{
}

virtual void operator ()(const Range& range) const CV_OVERRIDE
{
    for (int r = range.start; r < range.end; r++)
    {
        int i = r / m_img.cols;
        int j = r % m_img.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_img.ptr<uchar>(i)[j] = value;
    }
}

ParallelMandelbrot& operator=(const ParallelMandelbrot &) {
    return *this;
};

private:
Mat &m_img;
float m_x1;
float m_y1;
float m_scaleX;
float m_scaleY;
};
//! [mandelbrot-parallel]

//! [mandelbrot-sequential]
void sequentialMandelbrot(Mat &img, const float x1, const float y1, const float scaleX, const float scaleY)
{
for (int i = 0; i < img.rows; i++)
{
for (int j = 0; j < img.cols; j++)
{
float x0 = j / scaleX + x1;
float y0 = i / scaleY + y1;

        complex<float> z0(x0, y0);
        uchar value = (uchar) mandelbrotFormula(z0);
        img.ptr<uchar>(i)[j] = value;
    }
}

}
//! [mandelbrot-sequential]
}

int main()
{
//! [mandelbrot-transformation]
Mat mandelbrotImg(4800, 5400, CV_8U);
float x1 = -2.1f, x2 = 0.6f;
float y1 = -1.2f, y2 = 1.2f;
float scaleX = mandelbrotImg.cols / (x2 - x1); // 5400/2.7
float scaleY = mandelbrotImg.rows / (y2 - y1); // 4800/2.4
// cout << "scaleX = " << scaleX << endl;

//! [mandelbrot-transformation]

double t1 = (double) getTickCount();

#ifdef CV_CXX11

//! [mandelbrot-parallel-call-cxx11]
parallel_for_(Range(0, mandelbrotImg.rows*mandelbrotImg.cols), [&](const Range& range)
{
    for (int r = range.start; r < range.end; r++)
    {
        int i = r / mandelbrotImg.cols;
        int j = r % mandelbrotImg.cols;

        float x0 = j / scaleX + x1;
        float y0 = i / scaleY + y1;

        complex<float> z0(x0, y0);
        uchar value = (uchar) mandelbrotFormula(z0);
        mandelbrotImg.ptr<uchar>(i)[j] = value;
    }
});
//! [mandelbrot-parallel-call-cxx11]

#else

//! [mandelbrot-parallel-call]
ParallelMandelbrot parallelMandelbrot(mandelbrotImg, x1, y1, scaleX, scaleY);
parallel_for_(Range(0, mandelbrotImg.rows*mandelbrotImg.cols), parallelMandelbrot);
//! [mandelbrot-parallel-call]

#endif

t1 = ((double) getTickCount() - t1) / getTickFrequency();
cout << "Parallel Mandelbrot: " << t1 << " s" << endl;

Mat mandelbrotImgSequential(4800, 5400, 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;

imwrite("Mandelbrot_parallel.png", mandelbrotImg);
imwrite("Mandelbrot_sequential.png", mandelbrotImgSequential);
imshow("Mandelbrot_parallel.png", mandelbrotImg);
imshow("Mandelbrot_sequential.png", mandelbrotImgSequential);
waitKey();

return EXIT_SUCCESS;

}

发布了43 篇原创文章 · 获赞 0 · 访问量 401

猜你喜欢

转载自blog.csdn.net/weixin_42505877/article/details/103953951
今日推荐