C++AMP Вычисление градиента с использованием текстуры на 16-битном изображении

Я работаю с изображениями глубины, полученными из kinect, которые имеют 16 бит. Я обнаружил некоторые трудности при создании собственных фильтров из-за индекса или размера изображений. Я работаю с текстурами, потому что позволяет работать с изображениями любого размера.

Итак, я пытаюсь вычислить простой градиент, чтобы понять, что не так или почему это не работает, как я ожидал.

Вы можете видеть, что что-то не так, когда я использую y dir.

Для х:

Для тебя:

Это мой код:

typedef concurrency::graphics::texture<unsigned int, 2> TextureData;
typedef concurrency::graphics::texture_view<unsigned int, 2> Texture

cv::Mat image = cv::imread("Depth247.tiff", CV_LOAD_IMAGE_ANYDEPTH);

//just a copy from another image
cv::Mat image2(image.clone() );


concurrency::extent<2> imageSize(640, 480);
int bits = 16;

const unsigned int nBytes = imageSize.size() * 2; // 614400


{
    uchar* data = image.data;

    // Result data
    TextureData texDataD(imageSize, bits);
    Texture texR(texDataD);


    parallel_for_each(
        imageSize,
        [=](concurrency::index<2> idx) restrict(amp)
    {
        int x = idx[0];
        int y = idx[1];

        // 65535 is the maxium value that can take a pixel with 16 bits (2^16 - 1)
        int valX = (x / (float)imageSize[0]) * 65535;
        int valY = (y / (float)imageSize[1]) * 65535;

        texR.set(idx, valX);
    });
    //concurrency::graphics::copy(texR, image2.data, imageSize.size() *(bits / 8u));
    concurrency::graphics::copy_async(texR, image2.data, imageSize.size() *(bits) );

    cv::imshow("result", image2);
    cv::waitKey(50);
}

Любая помощь будет очень ценится.

1 ответ

Решение

Ваши индексы меняются местами в двух местах.

int x = idx[0];
int y = idx[1];

Помните, что C++AMP использует индексы основных рядов для массивов. таким образом idx[0] относится к строке, оси Y. Вот почему картинка для "For x" выглядит так, как я ожидаю texR.set(idx, valY),

Точно так же экстент изображения также использует измененные значения.

int valX = (x / (float)imageSize[0]) * 65535;
int valY = (y / (float)imageSize[1]) * 65535;

Вот imageSize[0] относится к количеству столбцов (значение y), а не к числу строк.

Я не знаком с OpenCV, но я предполагаю, что он также использует основной формат строки для cv::Mat, Это может инвертировать y ось с 0, 0 верхний левый, а не нижний левый. Данные Kinect могут делать схожие вещи, но опять же, это ряд строк.

В вашем коде могут быть другие места с такой же проблемой, но я думаю, что если вы дважды проверите, как вы используете index а также extent Вы должны быть в состоянии это исправить.

Другие вопросы по тегам