evermeer/PassportScanner

Issue cropping the image

alejandroruizponce opened this issue · 2 comments

Hi Edwin, first of all, thank you for your awesome framework. I've modified your interface with the camera as you can see in this image:

44b1affc-27de-460b-966c-babcd51ac82b

My problem now is in these lines when cropping is made:
// Specify the crop region that will be used for the OCR
crop.cropSizeInPixels = Size(width: 500, height: 1250)
crop.locationOfCropInPixels = Position(350, 60, nil)
crop.overriddenOutputRotation = .rotateClockwise

I need to modify the size and the location to fit the cropping for the new visible area, but I don't understand how works this methods, the documentation of GPUImage show very few information about it. If you can help me with an example I would thank you.

The source size of the video is Full HD = 1080 * 1920

With the:
crop.cropSizeInPixels = Size(width: 350, height: 1800)
here you specify that you only want to use a part of that which is only 350 * 1800
In your case it looks like the area is a little smaller. I estimate its closer to 200 * 1000

Then you have to specify the position of that area on your total video size with:
crop.locationOfCropInPixels = Position(350, 60, nil)
with the 60 we center the 1800 in the middle (60 + 1800 + 60 = 1920)
And with the 350 we almost center it in the video hight (350 + 350 is leaving + 380 = 1080)

GPUImage will get the image as in your screenshot so for a good scan it has to be rotated with
crop.overriddenOutputRotation = .rotateClockwise.

There is also a line of code that resizes the cropped region to 50%. This to change the number of pixels per letter for optimal OCR results. If you have less pixels per letter the OCR quality will go down and if you have more pixels per letter the OCR quality also goes down. So if you do change the crop area, then you also have to change the resize factor. The optimal size for the image of the MRZ is about 175 * 900 pixels. This is now achieved with the line:
let croppedImage: UIImage = sourceImage.resizedImageToFit(in: CGSize(width: 350 * 0.5, height: 1800 * 0.5), scaleIfSmaller: true)
There you should use the same numbers as you use in cropSizeInPixels but the factor can be changed probably to something between 0.8 and 1.1

when you set a breakpoint below the croppedImage, then you can inspect the image and see if you have the right image data.

Thank you very much, I solved the issue.