OpenCV -加速3x3个补丁的SSD的计算

OpenCV - Speeding up the computation of SSD of 3x3 patches

本文关键字:SSD 计算 补丁 加速 3x3 OpenCV      更新时间:2023-10-16

作为更大的应用程序的一部分,我需要计算以下代码:

ax2 += (int)(25 + 0.5);
ay2 += (int)(25 + 0.5);
bx2 += (int)(25 + 0.5);
by2 += (int)(25 + 0.5);
cx2 += (int)(25 + 0.5);
cy2 += (int)(25 + 0.5);
    for (int ix = -1; ix <= 1; ix++){
        for (int iy = -1; iy <= 1; iy++){
            suma += (grayImage.at<uchar>(ay2 + iy, ax2 + ix) - grayImage.at<uchar>(by2 + iy, bx2 + ix))* grayImage.at<uchar>(ay2 + iy, ax2 + ix) - grayImage.at<uchar>(by2 + iy, bx2 + ix));
}
}

它基本上计算两个3X3补丁的平方差和。

运行非常慢。有没有办法加快速度?

编辑:

我改成了以下版本:

for (int ix = -1; ix <= 1; ix++){
        for (int iy = -1; iy <= 1; iy++){
            double difa = grayImage.at<uchar>(ay2 + iy, ax2 + ix) - grayImage.at<uchar>(by2 + iy, bx2 + ix);
            suma += (difa)*(difa);
        }
}

它运行得更快,但是有没有办法进一步改进它?

谢谢,

吉尔。

编辑:在评论和答案之后,我没有使用以下代码:

//int iy = -1;
     Mi_a = grayImage.ptr<uchar>(ay2 - 1);
     Mi_b = grayImage.ptr<uchar>(by2 - 1);
     Mi_c = grayImage.ptr<uchar>(cy2 - 1);
    difa = Mi_a[ax2 - 1] - Mi_b[bx2 - 1];
    suma += (difa)*(difa);
    difc = Mi_c[cx2 - 1] - Mi_b[bx2 - 1];
    sumc += (difc)*(difc);
    difa = Mi_a[ax2 + 0] - Mi_b[bx2 + 0];
    suma += (difa)*(difa);
    difc = Mi_c[cx2 + 0] - Mi_b[bx2 + 0];
    sumc += (difc)*(difc);
    difa = Mi_a[ax2 + 1] - Mi_b[bx2 + 1];
    suma += (difa)*(difa);
    difc = Mi_c[cx2 + 1] - Mi_b[bx2 + 1];
    sumc += (difc)*(difc);

    //int iy=0;
    Mi_a = grayImage.ptr<uchar>(ay2 + 0);
    Mi_b = grayImage.ptr<uchar>(by2 + 0);
    Mi_c = grayImage.ptr<uchar>(cy2 + 0);
    difa = Mi_a[ax2 - 1] - Mi_b[bx2 - 1];
    suma += (difa)*(difa);
    difc = Mi_c[cx2 - 1] - Mi_b[bx2 - 1];
    sumc += (difc)*(difc);
    difa = Mi_a[ax2 + 0] - Mi_b[bx2 + 0];
    suma += (difa)*(difa);
    difc = Mi_c[cx2 + 0] - Mi_b[bx2 + 0];
    sumc += (difc)*(difc);
    difa = Mi_a[ax2 + 1] - Mi_b[bx2 + 1];
    suma += (difa)*(difa);
    difc = Mi_c[cx2 + 1] - Mi_b[bx2 + 1];
    sumc += (difc)*(difc);

    //int iy=1
    Mi_a = grayImage.ptr<uchar>(ay2 + 1);
    Mi_b = grayImage.ptr<uchar>(by2 + 1);
    Mi_c = grayImage.ptr<uchar>(cy2 + 1);
    difa = Mi_a[ax2 - 1] - Mi_b[bx2 - 1];
    suma += (difa)*(difa);
    difc = Mi_c[cx2 - 1] - Mi_b[bx2 - 1];
    sumc += (difc)*(difc);
    difa = Mi_a[ax2 + 0] - Mi_b[bx2 + 0];
    suma += (difa)*(difa);
    difc = Mi_c[cx2 + 0] - Mi_b[bx2 + 0];
    sumc += (difc)*(difc);
    difa = Mi_a[ax2 + 1] - Mi_b[bx2 + 1];
    suma += (difa)*(difa);
    difc = Mi_c[cx2 + 1] - Mi_b[bx2 + 1];
    sumc += (difc)*(difc);

或者是具有相同运行时间的循环版本:

for (int iy = -1; iy <= 1; iy++)
    {
        const uchar * Mi_a = grayImage.ptr<uchar>(ay2 + iy);
        const uchar * Mi_b = grayImage.ptr<uchar>(by2 + iy);
        const uchar * Mi_c = grayImage.ptr<uchar>(cy2 + iy);
        for (int ix = -1; ix <= 1; ix++)
        {
            double difa = Mi_a[ax2 + ix] - Mi_b[bx2 + ix];
            suma += (difa)*(difa);
            double difc = Mi_c[cx2 + ix] - Mi_b[bx2 + ix];
            sumc += (difc)*(difc);
        }
    }

有没有办法让它更快呢?

感谢

吉尔

来自OpenCv Mat文档

如果你需要处理2D数组的一整行,最有效的方法是先获得指向该行的指针,然后只使用普通的C操作符[]

:

for (int iy = -1; iy <= 1; iy++)
{
    const uchar * Mi_a = grayImage.ptr<uchar>(ay2 + iy);
    const uchar * Mi_b = grayImage.ptr<uchar>(by2 + iy);
    for (int ix = -1; ix <= 1; ix++)
    {
        double difa = Mi_a[ax2 + ix] - Mi_b[bx2 + ix]
        suma += (difa)*(difa);
    }    
}