GPUImage Harris Corner Detection на существующем UIImage дает вывод черного экрана

Я успешно добавил генератор перекрестия и фильтр обнаружения углов Харриса на выход GPUImageStillCamera, а также на живое видео с GPUImageVideoCamera.

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

Я пытался изменить каждую строку кода, чтобы следовать различным примерам, которые я видел, и следовать примеру кода Брэда в демонстрационных проектах Filter, но результат всегда один и тот же.

Мой текущий код, как только я сделал фотографию (которую я проверяю, чтобы убедиться, что на данный момент это не просто черная фотография):

GPUImagePicture *stillImageSource = [[GPUImagePicture alloc] initWithImage:self.photoView.image];

GPUImageHarrisCornerDetectionFilter *cornerFilter1 = [[GPUImageHarrisCornerDetectionFilter alloc] init];
[cornerFilter1 setThreshold:0.1f];
[cornerFilter1 forceProcessingAtSize:self.photoView.frame.size];

GPUImageCrosshairGenerator *crossGen = [[GPUImageCrosshairGenerator alloc] init];
crossGen.crosshairWidth = 15.0;
[crossGen forceProcessingAtSize:self.photoView.frame.size];

[cornerFilter1 setCornersDetectedBlock:^(GLfloat* cornerArray, NSUInteger cornersDetected, CMTime frameTime, BOOL endUpdating)
{
    [crossGen renderCrosshairsFromArray:cornerArray count:cornersDetected frameTime:frameTime];
}];


[stillImageSource addTarget:crossGen];
[crossGen addTarget:cornerFilter1];

[crossGen prepareForImageCapture];
[stillImageSource processImage];

UIImage *currentFilteredImage = [crossGen imageFromCurrentlyProcessedOutput];
UIImageWriteToSavedPhotosAlbum(currentFilteredImage, nil, nil, nil);
[self.photoView setImage:currentFilteredImage];

Я пробовал prepareForImageCapture на обоих фильтрах, ни на одном, добавляя две цели в обратном порядке, вызывая imageFromCurrentlyProcessedOutput на любом фильтре, я пробовал без генератора перекрестия, я пытался использовать локальные переменные и переменные, объявленные в файле . ч файл. Я пробовал с forceProcessingAtSize и без него на каждом из фильтров.

Я не могу думать ни о чем другом, что я не пытался получить результат. Приложение работает на iPhone 7.0 в Xcode 5.0.1. На фото работают стандартные фильтры, т.е. простой GPUImageSobelEdgeDetectionFilter, включенный в тестовое приложение SimpleImageFilter.

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

Спасибо.

Отредактировано, чтобы добавить: обнаружение углов определенно работает, так как в зависимости от установленного порога оно возвращает от 6 до 511 углов.


person wickets    schedule 25.11.2013    source источник


Ответы (3)


Проблема с вышеизложенным заключается в том, что вы не соединяете фильтры в правильном порядке. Детектор углов Харриса принимает входное изображение, находит в нем углы и предоставляет блок обратного вызова для возврата этих углов. GPUImageCrosshairGenerator принимает эти точки и создает визуальное представление углов.

То, что у вас есть в приведенном выше коде, это image->GPUImageCrosshairGenerator-> GPUImageHarrisCornerDetectionFilter, который на самом деле ничего не сделает.

Код в вашем ответе идет непосредственно от изображения к GPUImageHarrisCornerDetectionFilter, но вы не хотите использовать вывод изображения из него. Как вы видели, он создает изображение, в котором углы обозначены белыми точками на черном фоне. Вместо этого используйте блок обратного вызова, который обрабатывает это и возвращает массив нормализованных угловых координат для использования.

Если вам нужно, чтобы они были видны, вы можете затем взять этот массив координат и передать его в GPUImageCrosshairGenerator для создания видимых перекрестий, но это изображение нужно будет смешать с вашим исходным изображением, чтобы иметь какой-либо смысл. Это то, что я делаю в примере с FilterShowcase.

person Brad Larson    schedule 25.11.2013
comment
Спасибо, Брэд. Я изо всех сил пытаюсь соответствовать функциональности, которую вы имели в FilterShowcase, потому что я не уверен, как преобразовать то, что вы делаете для видеокамеры, в мой источник неподвижного изображения. - person wickets; 29.11.2013

Кажется, я исправил проблему, снова попробовав разные варианты, и теперь возвращаемое изображение черное, но в местах найденных углов есть белые точки. Я вообще удалил GPUImageCrosshairGenerator. Код, который заработал, был:

GPUImagePicture *stillImageSource = [[GPUImagePicture alloc] initWithImage:self.photoView.image];

GPUImageHarrisCornerDetectionFilter *cornerFilter1 = [[GPUImageHarrisCornerDetectionFilter alloc] init];
[cornerFilter1 setThreshold:0.1f];
[cornerFilter1 forceProcessingAtSize:self.photoView.frame.size];

[stillImageSource addTarget:cornerFilter1];
[cornerFilter1 prepareForImageCapture];
[stillImageSource processImage];

UIImage *currentFilteredImage = [cornerFilter1 imageFromCurrentlyProcessedOutput];
UIImageWriteToSavedPhotosAlbum(currentFilteredImage, nil, nil, nil);
[self.photoView setImage:currentFilteredImage];

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

person wickets    schedule 25.11.2013

Обновленный код для Swift 2:

 let stillImageSource: GPUImagePicture = GPUImagePicture(image: image)
 let cornerFilter1: GPUImageHarrisCornerDetectionFilter = GPUImageHarrisCornerDetectionFilter()
 cornerFilter1.threshold = 0.1

 cornerFilter1.forceProcessingAtSize(image.size)
 stillImageSource.addTarget(cornerFilter1)
 stillImageSource.processImage()
 let tmp: UIImage = cornerFilter1.imageByFilteringImage(image)
person David Sowsy    schedule 08.10.2015