Arhn - архитектура программирования

Изображения поворачиваются при преобразовании из Matrix

Я работаю над приложением и использую библиотеку opencv.

Проблема, с которой я сталкиваюсь, возникает только с определенными изображениями (обычно если они сделаны с помощью камеры телефона), и я определил, что это просто проблема преобразования. Когда я конвертирую (проблемное) изображение в объект cv::Mat, а затем обратно, оно просто поворачивается на 90 градусов.

Вот вызов, который вызывает проблему:

cv::Mat tmpMat = [sentImage CVMat];

UIImage * tmpImage = [[UIImage alloc] initWithCVMat:tmpMat];

[imageHolder setImage: tmpImage];

А вот функции, которые делают преобразование из изображения в матрицу и наоборот.

-(cv::Mat)CVMat
{

CGColorSpaceRef colorSpace = CGImageGetColorSpace(self.CGImage);
CGFloat cols = self.size.width;
CGFloat rows = self.size.height;

cv::Mat cvMat(rows, cols, CV_8UC4); // 8 bits per component, 4 channels

CGContextRef contextRef = CGBitmapContextCreate(cvMat.data,                 // Pointer to backing data
                                                cols,                      // Width of bitmap
                                                rows,                     // Height of bitmap
                                                8,                          // Bits per component
                                                cvMat.step[0],              // Bytes per row
                                                colorSpace,                 // Colorspace
                                                kCGImageAlphaNoneSkipLast |
                                                kCGBitmapByteOrderDefault); // Bitmap info flags

CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), self.CGImage);
CGContextRelease(contextRef);

return cvMat;
}


- (id)initWithCVMat:(const cv::Mat&)cvMat
{
NSData *data = [NSData dataWithBytes:cvMat.data length:cvMat.elemSize() * cvMat.total()];

CGColorSpaceRef colorSpace;

if (cvMat.elemSize() == 1)
{
    colorSpace = CGColorSpaceCreateDeviceGray();
}
else
{
    colorSpace = CGColorSpaceCreateDeviceRGB();
}

CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);

CGImageRef imageRef = CGImageCreate(cvMat.cols,                                     // Width
                                    cvMat.rows,                                     // Height
                                    8,                                              // Bits per component
                                    8 * cvMat.elemSize(),                           // Bits per pixel
                                    cvMat.step[0],                                  // Bytes per row
                                    colorSpace,                                     // Colorspace
                                    kCGImageAlphaNone | kCGBitmapByteOrderDefault,  // Bitmap info flags
                                    provider,                                       // CGDataProviderRef
                                    NULL,                                           // Decode
                                    false,                                          // Should interpolate
                                    kCGRenderingIntentDefault);                     // Intent

self = [self initWithCGImage:imageRef];
CGImageRelease(imageRef);
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpace);

return self;
}

Теперь я использую свойство "Aspect Fill" в моем imageHolder (UIImageView) и безуспешно пытался изменить его. Я также пытался посмотреть, была ли это проблема переноса матрицы при преобразовании, и пытался изменить безуспешно, и это также было бы нелогично, поскольку он не переворачивает каждую картинку.

Не понимаю, почему на одних фото работает, а на других нет (не работают все фото, сделанные камерой телефона).

Если кто-то может пролить свет на этот вопрос, я был бы признателен.

06.09.2013

  • Мое предложение состояло бы в том, чтобы проверить tmpMat сразу после заполнения его данными изображения. Посмотрите, имеет ли он одинаковую ориентацию как для обычных изображений, так и для изображений с камеры телефона, используя imshow(). Также проверьте типы перечисления вашей матрицы на наличие различий, используя tmpMat.type(). Если это ничего не показывает, я предполагаю, что способ хранения данных изображения в телефоне, вероятно, основан на столбцах, а не на строках. 06.09.2013

Ответы:


1

Изображения с камеры, снятые с разных ориентаций (книжная/альбомная), сохраняются камерой iPhone с одинаковым разрешением (одинаковое количество строк и столбцов). Разница в том, что JPEG содержит флаг (точнее, флаг Exif.Image.Orientation), чтобы сообщить программе отображения, как нужно повернуть изображение, чтобы оно отображалось правильно.

Я предполагаю, что OpenCV теряет эту информацию (которая хранится в UIImage в свойстве imageOrientation) при преобразовании, поэтому, когда изображение преобразуется обратно в UIImage, эта часть информации устанавливается по умолчанию (UIImageOrientationUp), что объясняет, почему некоторые изображения отображаются быть повернуты.

08.09.2013
  • Это было именно так! Спасибо! 18.09.2013

  • 2

    У меня была такая же проблема. Это решает проблему вращения изображения при преобразовании из UIImage в cvMat. Добавьте метод внизу, вызовите его после закрытия контроллера выбора. Это «второй ответ», расположенный здесь: Вращение CGImage

    Кроме того, в файле ios.h есть два метода преобразования UIImage в cvMat и наоборот, которые вы можете просто включить. highgui/ios.h. Затем добавьте метод вращения, и все готово.

    04.12.2013
    Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..