Самый быстрый способ поместить изображение в непоследовательное измерение - PullRequest
0 голосов
/ 07 февраля 2019

У меня есть изображение 700x2000 uint8.Теперь я хочу выполнить bin, то есть вычислить сумму для каждых 4 строк, которые не являются последовательными в памяти.

Прямо сейчас я выделяю новый массив для этой суммы строки и для каждой строки в ней,

float* binnedLine = new float[lineSize];
char* binnedLineInt = new char[lineSize];

for (int j = 0; j < nlines; j++) 
{
    if (j % binsize == 0) 
    {
        for (int i = 0; i < lineSize; i++) 
        {
            binnedLine[i] = (static_cast<float> (static_cast<char>(data[j*lineSize + i]))) / binsize;
            binnedLineInt[i] = static_cast<char>(binnedLine[i]);
        };
    }
    else 
    {
        for (int i = 0; i < lineSize; i++) 
        {
            binnedLine[i] += (static_cast<float> (static_cast<char>(data[j*lineSize + i]))) / binsize;
            binnedLineInt[i] = static_cast<char>(binnedLine[i]);
        };
    }

    ...
}

Однако для моих целей производительность действительно недостаточна (она занимает 3 мс на кадр).Есть ли более эффективный способ?

1 Ответ

0 голосов
/ 07 февраля 2019

Вы конвертируете значения с плавающей запятой в char 4 раза, но сохраняете только последнее преобразование.В то же время мы удалим if и %, а также избежим лишних делений.Попробуйте это:

float* binnedLine = new float[lineSize];
char* binnedLineInt = new char[lineSize];

for (int j = 0; j < nlines; j += binsize) 
{
    for (int i = 0; i < lineSize; ++i) 
    {
        binnedLine[i] = static_cast<float>(data[j*lineSize + i]);
    };
    for (int k = 1; k < binsize; ++k)
    {
        for (int i = 0; i < lineSize; ++i) 
        {
            binnedLine[i] += static_cast<float>(data[(j+k)*lineSize + i]);
        };
    }
    for (int i = 0; i < lineSize; ++i) 
    {
        binnedLineInt[i] = static_cast<char>(binnedLine[i] / binsize);
    }
    ...
}

Но, как сказал @ MSalters в комментарии , вам, вероятно, лучше сразу получить доступ к четырем строкам, так как это позволит избежать удержания и записи в дополнительный float.буфер:

char* binnedLineInt = new char[lineSize];

for (int j = 0; j < nlines; j += binsize) 
{
    for (int i = 0; i < lineSize; ++i) 
    {
        float sum = static_cast<float>(data[j*lineSize + i]);
        for (int k = 1; k < binsize; ++k)
        {
            sum += static_cast<float>(data[(j+k)*lineSize + i]);
        }
        binnedLineInt[i] = static_cast<char>(sum / binsize);
    }
    ...
}

Кроме того, более короткий код легче понять и легче поддерживать.

...