iOS Question How To use CIDetector

hanyelmehy

Active Member
Licensed User
Longtime User
Any one know how to make this code and return result to B4I
B4X:
    CIImage *imggo = //source image
    NSDictionary *options = @{CIDetectorAccuracy: CIDetectorAccuracyHigh, CIDetectorAspectRatio: @(1.0)};
    CIDetector *rectangleDetector = [CIDetector detectorOfType:CIDetectorTypeRectangle context:nil options:options];

    NSArray *rectangleFeatures = [rectangleDetector featuresInImage:imggo];

    for (CIRectangleFeature *rectangleFeature in rectangleFeatures) {
        CGPoint topLeft = rectangleFeature.topLeft;
        CGPoint topRight = rectangleFeature.topRight;
        CGPoint bottomLeft = rectangleFeature.bottomLeft;
        CGPoint bottomRight = rectangleFeature.bottomRight;
    }
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Start with this:
B4X:
Dim no As NativeObject = Me
   Dim res As List = no.RunMethod("detectRects:", Array(LoadBitmap(File.DirAssets, "squares.png")))
   Log(res)
   For Each feature As NativeObject In res
     Log(feature.GetField("bounds"))
   Next

#if OBJC
@import CoreImage;
- (NSArray*) detectRects: (UIImage*)img {
int exifOrientation;
switch (img.imageOrientation) {
  case UIImageOrientationUp:
  exifOrientation = 1;
  break;
  case UIImageOrientationDown:
  exifOrientation = 3;
  break;
  case UIImageOrientationLeft:
  exifOrientation = 8;
  break;
  case UIImageOrientationRight:
  exifOrientation = 6;
  break;
  case UIImageOrientationUpMirrored:
  exifOrientation = 2;
  break;
  case UIImageOrientationDownMirrored:
  exifOrientation = 4;
  break;
  case UIImageOrientationLeftMirrored:
  exifOrientation = 5;
  break;
  case UIImageOrientationRightMirrored:
  exifOrientation = 7;
  break;
  default:
  break;
}

NSDictionary *detectorOptions = @{ CIDetectorAccuracy : CIDetectorAccuracyHigh };
CIDetector *faceDetector = [CIDetector detectorOfType:CIDetectorTypeRectangle  context:nil options:detectorOptions];

NSArray *features = [faceDetector featuresInImage:[CIImage imageWithCGImage:img.CGImage]
  options:@{CIDetectorImageOrientation:[NSNumber numberWithInt:exifOrientation]}];
   return features;
}
#end if
 
Upvote 0

hanyelmehy

Active Member
Licensed User
Longtime User
Start with this:
B4X:
Dim no As NativeObject = Me
   Dim res As List = no.RunMethod("detectRects:", Array(LoadBitmap(File.DirAssets, "squares.png")))
   Log(res)
   For Each feature As NativeObject In res
     Log(feature.GetField("bounds"))
   Next

#if OBJC
@import CoreImage;
- (NSArray*) detectRects: (UIImage*)img {
int exifOrientation;
switch (img.imageOrientation) {
  case UIImageOrientationUp:
  exifOrientation = 1;
  break;
  case UIImageOrientationDown:
  exifOrientation = 3;
  break;
  case UIImageOrientationLeft:
  exifOrientation = 8;
  break;
  case UIImageOrientationRight:
  exifOrientation = 6;
  break;
  case UIImageOrientationUpMirrored:
  exifOrientation = 2;
  break;
  case UIImageOrientationDownMirrored:
  exifOrientation = 4;
  break;
  case UIImageOrientationLeftMirrored:
  exifOrientation = 5;
  break;
  case UIImageOrientationRightMirrored:
  exifOrientation = 7;
  break;
  default:
  break;
}

NSDictionary *detectorOptions = @{ CIDetectorAccuracy : CIDetectorAccuracyHigh };
CIDetector *faceDetector = [CIDetector detectorOfType:CIDetectorTypeRectangle  context:nil options:detectorOptions];

NSArray *features = [faceDetector featuresInImage:[CIImage imageWithCGImage:img.CGImage]
  options:@{CIDetectorImageOrientation:[NSNumber numberWithInt:exifOrientation]}];
   return features;
}
#end if
i try to use CIPerspectiveCorrection and return filtered bitmap with no success can you please check this
B4X:
- (UIImage*) detectRects2: (UIImage*)img {
int exifOrientation;
switch (img.imageOrientation) {
  case UIImageOrientationUp:
  exifOrientation = 1;
  break;
  case UIImageOrientationDown:
  exifOrientation = 3;
  break;
  case UIImageOrientationLeft:
  exifOrientation = 8;
  break;
  case UIImageOrientationRight:
  exifOrientation = 6;
  break;
  case UIImageOrientationUpMirrored:
  exifOrientation = 2;
  break;
  case UIImageOrientationDownMirrored:
  exifOrientation = 4;
  break;
  case UIImageOrientationLeftMirrored:
  exifOrientation = 5;
  break;
  case UIImageOrientationRightMirrored:
  exifOrientation = 7;
  break;
  default:
  break;
}

NSDictionary *detectorOptions = @{ CIDetectorAccuracy : CIDetectorAccuracyHigh };
CIDetector *faceDetector = [CIDetector detectorOfType:CIDetectorTypeRectangle  context:nil options:detectorOptions];

NSArray *features = [faceDetector featuresInImage:[CIImage imageWithCGImage:img.CGImage]
  options:@{CIDetectorImageOrientation:[NSNumber numberWithInt:exifOrientation]}];
  
   CIImage *resultImage = [image copy];
        for (CIRectangleFeature *feature1 in *features) {
            resultImage = [image imageByApplyingFilter:@"CIPerspectiveCorrection"
                                   withInputParameters:@{@"inputTopLeft":[CIVector vectorWithCGPoint:feature1.topLeft] ,
                                                         @"inputTopRight": [CIVector vectorWithCGPoint:feature1.topRight],
                                                         @"inputBottomLeft": [CIVector vectorWithCGPoint:feature1.bottomLeft],
                                                         @"inputBottomRight": [CIVector vectorWithCGPoint:feature1.bottomRight]}];
        }
 
    //CIImage *outputImage = filter.outputImage;
    CIContext *context = [CIContext contextWithOptions:nil];
    CGImageRef outImage = [context createCGImage: resultImage
                                        fromRect: [outputImage extent]];
    return [UIImage imageWithCGImage: outImage];
}
 
Upvote 0

hanyelmehy

Active Member
Licensed User
Longtime User
Start with this:
B4X:
Dim no As NativeObject = Me
   Dim res As List = no.RunMethod("detectRects:", Array(LoadBitmap(File.DirAssets, "squares.png")))
   Log(res)
   For Each feature As NativeObject In res
     Log(feature.GetField("bounds"))
   Next

#if OBJC
@import CoreImage;
- (NSArray*) detectRects: (UIImage*)img {
int exifOrientation;
switch (img.imageOrientation) {
  case UIImageOrientationUp:
  exifOrientation = 1;
  break;
  case UIImageOrientationDown:
  exifOrientation = 3;
  break;
  case UIImageOrientationLeft:
  exifOrientation = 8;
  break;
  case UIImageOrientationRight:
  exifOrientation = 6;
  break;
  case UIImageOrientationUpMirrored:
  exifOrientation = 2;
  break;
  case UIImageOrientationDownMirrored:
  exifOrientation = 4;
  break;
  case UIImageOrientationLeftMirrored:
  exifOrientation = 5;
  break;
  case UIImageOrientationRightMirrored:
  exifOrientation = 7;
  break;
  default:
  break;
}

NSDictionary *detectorOptions = @{ CIDetectorAccuracy : CIDetectorAccuracyHigh };
CIDetector *faceDetector = [CIDetector detectorOfType:CIDetectorTypeRectangle  context:nil options:detectorOptions];

NSArray *features = [faceDetector featuresInImage:[CIImage imageWithCGImage:img.CGImage]
  options:@{CIDetectorImageOrientation:[NSNumber numberWithInt:exifOrientation]}];
   return features;
}
#end if
This return :
<B4INativeObject: NSRect: {{159.72307, 247.96175}, {207.74602, 150.38988}}>
i think it must return 4 points(TopLeft,TopRight,BottomLeft,BottomRight) ?
is there are easy way to just return coordinate number only ?
Thank you
 
Upvote 0

hanyelmehy

Active Member
Licensed User
Longtime User
It prints the top left and bottom right points. You will need to extract them from the string.

You can post a feature request for a library that supports CIDetector.
can we return the 4 points(TopLeft,TopRight,BottomLeft,BottomRight) , top left and bottom right points are not enough to get the correct shape
 
Upvote 0

hanyelmehy

Active Member
Licensed User
Longtime User
Try this:
B4X:
For Each feature As NativeObject In res
Log(feature.GetField("bottomRight"))
Log(feature.GetField("topLeft"))
Log(feature.GetField("topRight"))
Log(feature.GetField("bottomLeft"))
Next
its work ,thank you
 
Upvote 0
Top