с учетом серого cv :: Mat (CV_8UC1) Я хочу вернуть еще один cv :: Mat, содержащий квадратный корень из элементов (CV_32FC1), и я хочу сделать это с помощью встроенных SSE2 , У меня возникают некоторые проблемы с преобразованием из 8-битных значений в 32 значения float для выполнения квадратного корня. Я бы очень признателен за любую помощь. Это мой код сейчас (это не дает правильные значения):Квадратный корень серого изображения OpenCV с использованием SSE
uchar *source = (uchar *)cv::alignPtr(image.data, 16);
float *sqDataPtr = cv::alignPtr((float *)Squared.data, 16);
for (x = 0; x < (pixels - 16); x += 16) {
__m128i a0 = _mm_load_si128((__m128i *)(source + x));
__m128i first8 = _mm_unpacklo_epi8(a0, _mm_set1_epi8(0));
__m128i last8 = _mm_unpackhi_epi8(a0, _mm_set1_epi8(0));
__m128i first4i = _mm_unpacklo_epi16(first8, _mm_set1_epi16(0));
__m128i second4i = _mm_unpackhi_epi16(first8, _mm_set1_epi16(0));
__m128 first4 = _mm_cvtepi32_ps(first4i);
__m128 second4 = _mm_cvtepi32_ps(second4i);
__m128i third4i = _mm_unpacklo_epi16(last8, _mm_set1_epi16(0));
__m128i fourth4i = _mm_unpackhi_epi16(last8, _mm_set1_epi16(0));
__m128 third4 = _mm_cvtepi32_ps(third4i);
__m128 fourth4 = _mm_cvtepi32_ps(fourth4i);
// Store
_mm_store_ps(sqDataPtr + x, _mm_sqrt_ps(first4));
_mm_store_ps(sqDataPtr + x + 4, _mm_sqrt_ps(second4));
_mm_store_ps(sqDataPtr + x + 8, _mm_sqrt_ps(third4));
_mm_store_ps(sqDataPtr + x + 12, _mm_sqrt_ps(fourth4));
}
Большое спасибо за ваш ответ, но я не копировал оставшиеся вычисления последних пикселей здесь для простоты. Этот код, я не знаю, почему не приводит к правильным значениям. Да, мне нужен квадратный корень из значений между 0 ... 255. Я не знаю, если это полностью эффективно. – user3696558
OK - петля все еще нуждается в исправлении, хотя, ради производительности, поскольку вам не хватает возможности обработать один последний полный вектор. Что касается функциональности, я подозреваю, что проблема может быть где-то иначе, чем в коде SSE - возможно, попробуйте заменить код SSE на простой скалярный цикл, чтобы увидеть, работает ли это, или проверить цикл SSE в отдельной тестовой проводке, чтобы проверить это? –
Еще одна вещь - я помещаю ваш SSE-код в тестовую жгуту, и она проходит (как только верхняя граница цикла цикла исправлена). –