#ios #objective-c #opencv #core-graphics
#iOS #objective-c #opencv #ядро-графика
Вопрос:
Я использую OpenCV для обнаружения лица на изображении, однако мой вопрос не связан с opencv, я думаю, что он связан только с CoreGraphics. Вот мой код в UIImageView (категория) для определения лица и рисования прямоугольника над ним.
- (void)detectFeature:(NSString *)feature
{
NSUInteger scale;
IplImage * image;
IplImage * smallImage;
NSString * xmlPath;
CvHaarClassifierCascade * cascade;
CvMemStorage * storage;
CvSeq * faces;
UIAlertView * alert;
CGImageRef imageRef;
CGColorSpaceRef colorSpaceRef;
CGContextRef context;
CvRect rect;
CGRect faceRect;
scale = 2;
cvSetErrMode( CV_ErrModeParent );
xmlPath = [ [ NSBundle mainBundle ] pathForResource: feature ofType: @"xml" ];
if (xmlPath == nil) {
NSLog(@"we don't have an xml file for this feature. this feature is can not be detacted");
}
else {
[self scaleAndRotateImage:self.image];
image = [ self createIplImage: self.image ];
smallImage = cvCreateImage( cvSize( image->width / scale, image->height / scale ), IPL_DEPTH_8U, 3 );
cvPyrDown( image, smallImage, CV_GAUSSIAN_5x5 );
cascade = ( CvHaarClassifierCascade * )cvLoad( [ xmlPath cStringUsingEncoding: NSASCIIStringEncoding ], NULL, NULL, NULL );
storage = cvCreateMemStorage( 0 );
faces = cvHaarDetectObjects( smallImage, cascade, storage, ( float )1.2, 2, CV_HAAR_DO_CANNY_PRUNING, cvSize( 20, 20 ) );
cvReleaseImage( amp;smallImage );
imageRef = self.image.CGImage;
colorSpaceRef = CGColorSpaceCreateDeviceRGB();
context = CGBitmapContextCreate
(
NULL,
self.image.size.width,
self.image.size.height,
8,
self.image.size.width * 4,
colorSpaceRef,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrderDefault
);
CGContextDrawImage
(
context,
CGRectMake( 0, 0, self.image.size.width, self.image.size.height ),
imageRef
);
CGContextSetLineWidth( context, 1 );
CGContextSetRGBStrokeColor( context, ( CGFloat )0, ( CGFloat )0, ( CGFloat )0, ( CGFloat )0.5 );
CGContextSetRGBFillColor( context, ( CGFloat )1, ( CGFloat )1, ( CGFloat )1, ( CGFloat )0.5 );
if( faces->total == 0 )
{
alert = [ [ UIAlertView alloc ] initWithTitle: @"No Feature" message: @"No features were detected in the picture. Please try with another one." delegate: NULL cancelButtonTitle: @"OK" otherButtonTitles: nil ];
[ alert show ];
}
else
{
for( int i = 0; i < faces->total; i )
{
rect = *( CvRect * )cvGetSeqElem( faces, i );
faceRect = CGContextConvertRectToDeviceSpace( context, CGRectMake( rect.x * scale, rect.y * scale, rect.width * scale, rect.height * scale ) );
CGContextFillRect( context, faceRect );
CGContextStrokeRect( context, faceRect );
}
self.image = [ UIImage imageWithCGImage: CGBitmapContextCreateImage( context ) ];
}
CGContextRelease( context );
CGColorSpaceRelease( colorSpaceRef );
cvReleaseMemStorage( amp;storage );
cvReleaseHaarClassifierCascade( amp;cascade );
cvReleaseImage( amp;smallImage );
}
}
Что делает этот код, так это рисует прямоугольник над моим UIImage. и оставьте остальную часть изображения как есть. Я хотел бы изменить всю область UIImage на черный, кроме обнаруженного прямоугольника.
На данный момент мне удалось обрезать изображение. Но я не хочу этого делать. размер изображения должен быть таким же, я просто хочу затемнить остальную область изображения.
Комментарии:
1. У меня сейчас нет доступного кода, но я знаю, что вы можете выполнять операции с масками с помощью OpenCV, которые должны выполнить то, что вы хотите.
Ответ №1:
Я пошагово разбил свой ответ.Надеюсь, это поможет.
После обнаружения всех граней нарисуйте заполненную прямоугольную область вместо пути в качестве нового изображения. После этого нарисуйте черное изображение исходного размера.
Затем создайте новый контекст, нарисуйте черное изображение, затем нарисуйте изображение пути (изображение с прямым путем) с помощью kCGBlendModeDestinationOut в режиме наложения.Сохраните результат как result1.
Снова создайте новый контекст, нарисуйте исходное изображение, затем нарисуйте изображение пути (изображение с прямым путем) с помощью KCGBLENDMODEDESTINATION в режиме наложения.Сохраните результат как result2.
Возьмите новый контекст и нарисуйте оба изображения result1 и result2 kCGBlendModeNormal . Надеюсь, это поможет. Удачного кодирования .. !!
Комментарии:
1. Я понимаю вашу точку зрения. просто возникли трудности с переводом в реальный код.
2. Если вы предоставите мне образец изображения, то есть оригинал, и изображение с полученным вами путем. Я могу предоставить пример кода.
3. В моем коде я уже использую Rect для рисования в контексте, подобном этому — CGContextFillRect (контекст, faceRect ). я не использую какой-либо путь сортировки.
4. «Что делает этот код, он рисует прямоугольник над моим UIImage» я спрашиваю это изображение.