OpenCV的中高效的像素遍歷方法,寫出工程級像素遍歷代碼 [ C++ OpenCV 依序取出像素值的各種寫法 – 越後面效率越高,但越看不懂 ]

OpenCV的中高效的像素遍歷方法,寫出工程級像素遍歷代碼 [ C++ OpenCV 依序取出像素值的各種寫法 – 越後面效率越高,但越看不懂 ]

OpenCV的中高效的像素遍歷方法,寫出工程級像素遍歷代碼 [ C++ OpenCV 依序取出像素值的各種寫法 – 越後面效率越高,但越看不懂 ]


資料來源:https://mp.weixin.qq.com/s/jfLdvLgAuCVclWkut9LH4g


方法ㄧ:

void method_1(Mat &image) {
    double t1 = getTickCount();
    int w = image.cols;
    int h = image.rows;
    for (int row = 0; row < h; row++) {
        for (int col = 0; col < w; col++) {
            Vec3b bgr = image.at<Vec3b>(row, col);
            bgr[0] = 255 - bgr[0];
            bgr[1] = 255 - bgr[1];
            bgr[2] = 255 - bgr[2];
            image.at<Vec3b>(row, col) = bgr;
        }
    }
    double t2 = getTickCount();
    double t = ((t2 - t1) / getTickFrequency()) * 1000;
    ostringstream ss;
    ss << "Execute time : " << std::fixed << std::setprecision(2) << t << " ms ";
    putText(image, ss.str(), Point(20, 20), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(0, 0, 255), 2, 8);
    imshow("result", image);
}

方法二:

void method_2(Mat &image) {
    double t1 = getTickCount();
    int w = image.cols;
    int h = image.rows;
    for (int row = 0; row < h; row++) {
        Vec3b* curr = image.ptr<Vec3b>(row);
        for (int col = 0; col < w; col++) {
            Vec3b bgr = curr[col];
            bgr[0] = 255 - bgr[0];
            bgr[1] = 255 - bgr[1];
            bgr[2] = 255 - bgr[2];
        }
    }
    double t2 = getTickCount();
    double t = ((t2 - t1) / getTickFrequency()) * 1000;
    ostringstream ss;
    ss << "Execute time : " << std::fixed << std::setprecision(2) << t << " ms ";
    putText(image, ss.str(), Point(20, 20), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(0, 0, 255), 2, 8);
    imshow("result", image);
}

/*
除了上述的行指針遍歷方式,常見的行指針還有如下:

CV_8UC1: 灰度图像
uchar* ptr = image.ptr<uchar>(row_index);

CV_8UC3: 彩色图像
Vec3b* ptr = image.ptr<cv::Vec3b>(row_index);

CV_32FC1: 单通道浮点数图像
float* ptr = image.ptr<float>(row_index);

CV_32FC3: 三通道浮点数图像
Vec3f* ptr = image.ptr<cv::Vec3f>(row_index);

*/

方法三:

void method_3(Mat &image) {
    double t1 = getTickCount();
    int w = image.cols;
    int h = image.rows;
    for (int row = 0; row < h; row++) {
        uchar* uc_pixel = image.data + row*image.step;
        for (int col = 0; col < w; col++) {
            uc_pixel[0] = 255 - uc_pixel[0];
            uc_pixel[1] = 255 - uc_pixel[1];
            uc_pixel[2] = 255 - uc_pixel[2];
            uc_pixel += 3;
        }
    }
    double t2 = getTickCount();
    double t = ((t2 - t1) / getTickFrequency()) * 1000;
    ostringstream ss;
    ss << "Execute time : " << std::fixed << std::setprecision(2) << t << " ms ";
    putText(image, ss.str(), Point(20, 20), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(0, 0, 255), 2, 8);
    imshow("result", image);
}

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *