У меня есть 8-битное изображение. Для каждого пикселя мне нужно определить его порядковое положение в текущей строке. Например, если строка:Нужна помощь в векторизации этого кода
32 128 16 64,
тогда я нужен результат:
1 3 0 2,
, поскольку 32 является первым наибольшее значение в строке, 128 третий самый высокий, 16 0th высоким и 64 является вторым по величине.
Мне нужно повторить описанную выше процедуру для всех строк изображения. Вот, не Векторизованные коды:
for (int curr = 0; curr < new_height; ++curr)
{
vector<pair<unsigned char, char> > ordered;
for (char i = 0; i < 4; ++i)
{
unsigned char val = luma24.at<unsigned char>(curr, i);
ordered.push_back(pair<unsigned char, char>(val, i));
}
sort(ordered.begin(), ordered.end(), cmpfun);
for (int i = 0; i < 4; ++i)
signature.at<char>(curr, ordered[i].second) = i;
}
luma24
является 8-битным изображением Читаю с, и она имеет new_height
строк и 4 столбца. signature
- это подписанное изображение того же размера (на данный момент игнорируйте разницу в знаке, поскольку оно не имеет значения) - это то место, где я сохраняю результат. cmpfun
- тривиальная функция компаратора.
Я пытался векторизацией выше кода и получил это:
Mat ordinal;
luma24.convertTo(ordinal, CV_16UC1, 256, 0);
Mat sorted = ordinal.clone();
for (int i = 0; i < 4; ++i)
ordinal(Range::all(), Range(i, i+1)) += i;
cv::sort(ordinal, sorted, CV_SORT_EVERY_ROW | CV_SORT_ASCENDING);
bitwise_and(sorted, Scalar(0x00ff), ordinal);
Mat ordinal8;
ordinal.convertTo(ordinal8, CV_8SC1, 1, 0);
ordinal8.copyTo(signature(Range::all(), Range(0, 4)));
мне пришлось упаковать значение 8-битное и 8-битовые порядковый номер в одном 16-разрядный канал, так как OpenCV не выполняет сортировать для многоканальных изображений. Это почти то, что мне нужно, но не совсем. Для примера входных данных, он дает мне:
2 0 3 1
, так как наименьшее значение находится в 2-м столбце, следующий наименьший в 0-я колонна и т.д. Как я могу идти о преобразовании этого в результате мне нужно без доступ к каждому пикселю индивидуально?
По существу, мне нужно как-то векторизации это:
uint8_t x[] = {2, 0, 3, 1};
uint8_t y[4];
for (uint8_t i = 0; i < 4; ++i)
y[x[i]] = i;
где x
промежуточный результат мой текущий Векторизованных код дает мне и y
результат я хочу.
Можно ли это сделать?
Для уточнения (у меня пока нет ответа) - Что вы хотите сделать, если у вас несколько пикселей с одинаковым значением? Должны ли они быть тем же порядком? –
Off topic: Какое совпадение, просто на днях я читал исходный код [ffmpeg tutorial] (https://github.com/mpenkov/ffmpeg-tutorial), который вы отразили на github. URL-адрес перестает работать, поэтому я пошел в ваш профиль, если вы его переименовали, но я думаю, вы его удалили, и сейчас я случайно узнал вашего аватара. –
В этом виде это почти невозможно. Какие существуют ограничения? например x [] всегда 4 элемента в ширину? должен ли он вместо uint8_t? –