Обрезка изображения Kinect

#c# #wpf #image #kinect

#c# #wpf #kinect

Вопрос:

Я пытаюсь обрезать прямоугольную область видео RGB. Сначала я нашел координаты соединения головы и с помощью этих координат нарисовал прямоугольник над видео RGB. Теперь я хочу показать в другом видео только изображение, которое находится внутри rentangle на первом изображении. Любая помощь была бы отличной.

видео RGB отображается в элементе управления изображением «RGBvideo». обрезанное изображение, которое я хочу отобразить в элементе управления изображением «Изображение лица»

Я искал в Интернете, но не смог найти решение этой проблемы. Я в замешательстве.

большое вам спасибо

Ответ №1:

Добро пожаловать в Stack Overflow, пожалуйста, не задавайте один и тот же вопрос несколько раз. С менее популярными тегами, такими как Kinect, людям может потребоваться некоторое время, чтобы ответить (у тега всего 79 подписчиков).

Для простоты я собираюсь предположить, что вы хотите обрезать изображение заданного размера (например, 60×60 пикселей из исходного 800×600). В вашем методе VideoFrameReady вы получаете плоское изображение из аргументов события. Это плоское изображение имеет поле bits, которое содержит все данные RGB для изображения. С помощью небольшой математики вы можете вырезать небольшой фрагмент этих данных и использовать его в качестве уменьшенного изображения.

 // update video feeds
void nui_VideoFrameReady(object sender, ImageFrameReadyEventArgs e)
{
    PlanarImage image = e.ImageFrame.Image;

    // Large video feed
    video.Source = BitmapSource.Create(image.Width, image.Height, 96, 96, PixelFormats.Bgr32, null, image.Bits, image.Width * image.BytesPerPixel);

    // X and Y coordinates of the smaller image, and the width and height of smaller image
    int xCoord = 100, yCoord = 150, width = 60, height = 60;

    // Create an array to copy data into
    byte[] bytes = new byte[width * height * image.BytesPerPixel];

    // Copy over the relevant bytes
    for (int i = 0; i < height; i  ) 
    {
        for (int j = 0; j < width * image.BytesPerPixel; j  )
        {
            bytes[i * (width * image.BytesPerPixel)   j] = image.Bits[(i   yCoord) * (image.Width * image.BytesPerPixel)   (j   xCoord * image.BytesPerPixel)];
        }
    }

    // Create the smaller image
    smallVideo.Source = BitmapSource.Create(width, height, 96, 96, PixelFormats.Bgr32, null, bytes, width * image.BytesPerPixel);
}
  

Пожалуйста, убедитесь, что вы понимаете код, а не просто копируете / вставляете его. Два цикла for предназначены для копирования базового массива с учетом количества байтов на пиксель (4 для BGR32). Затем вы используете это небольшое подмножество исходных данных для создания нового BitmapSource. Вам нужно, чтобы вы могли изменять ширину / высоту по своему усмотрению и определять координаты X и Y из отслеживания головы.

Комментарии:

1. Спасибо за вашу помощь! Но это просто останется в положении. Поэтому, если я хочу отслеживать свою голову, когда моя голова движется, smallVideo также будет перемещаться, чтобы поместить мою голову в элемент управления изображением. как это сделать? То, что вы дали, в любом случае мне очень помогло!

2. @user981924: что вам нужно сделать, так это сделать переменные xCoord и yCoord глобальными. Затем, при событии SkeletonFrameReady, измените эти переменные в зависимости от расположения заголовка. Просто убедитесь, что вы сохраняете значения в пределах границ (например, если xCoord или yCoord меньше 0, вы рискуете получить исключение OutOfBoundsException).

3. Исправлена ошибка в коде, по-видимому, не очень хорошо тестировал код.

4. Хорошо, спасибо! мне как-то удается следить за своей головой, но цвет элемента управления изображением (smallVideo) продолжает меняться с фиолетового на зеленый, на белый и бла-бла-бла. я имею в виду, что оно постоянно меняется, как будто оно нестабильно. но в любом случае, сейчас он работает. Спасибо!

5. @user981924: изменение цвета вызвано ошибкой, которую я допустил в коде. При назначении байта значение xCoord должно быть умножено на изображение. Байт-пиксель в правой половине уравнения. Обновите это и повторите попытку. Я отредактировал код в сообщении, чтобы отразить это изменение.