使用VNRectangleObservation裁剪UIImage

问题描述 投票:0回答:2

我正在使用Vision框架来检测捕获的照片中的矩形文档。检测并在文档周围绘制路径效果很好。然后,我想将图像裁剪为仅检测到的文档。我已经成功裁剪了图像,但是似乎坐标没有对齐,并且裁剪后的图像只是检测到的文档的一部分,其余的只是文档后面的桌子。我正在使用以下裁剪代码:

private UIImage CropImage(UIImage image, CGRect rect, float scale)
{
    var drawRect = new CGRect(rect.X, rect.Y, rect.Size.Width, rect.Size.Height);
    using (var cgImage = image.CGImage.WithImageInRect(drawRect))
    {
        var croppedImage = UIImage.FromImage(cgImage);
        return croppedImage;
    };
}

使用以下参数:

图像是我成功在其上绘制矩形路径的同一UIImage。

rect是VNRectangleObservation.BoundingBox。这是规范化的,因此我正在使用image.size对其进行缩放。这与绘制矩形路径时的缩放比例相同。

比例为1f,但我目前对此忽略。

裁切后的图像通常看起来是正确的尺寸,但是它向上移动并向左移动,从而切断了文档的左右两侧。任何帮助,将不胜感激。

ios xamarin xamarin.ios uiimage
2个回答
0
投票

裁切后的图像通常看起来是正确的尺寸,但是它向上移动并向左移动,从而切断了文档的左右两侧。

从Apple文档CGImageCreateWithImageInRect,有关于裁切尺寸的讨论。

CGImageCreateWithImageInRect执行以下任务来创建子图像:

  • 它调用CGRectIntegral函数将rect参数调整为整数范围。

  • 它与矩形相交,矩形的原点为(0,0),并且大小等于image参数指定的图像大小。

  • 它读取结果矩形内的像素,并将其中的第一个像素视为子图像的原点。

如果WH分别是图像的宽度和高度,则点(0,0)对应于图像数据的第一个像素。点(W–1, 0)是图像数据的第一行的最后一个像素,而(0, H–1)是图像数据的最后一行的最后一个像素,(W–1, H–1)是图像数据的最后一行的最后一个像素。

然后,您可以使用以下图像(尺寸为:1920 * 1080)检入本地项目:

UIImageView imageView = new UIImageView(new CGRect(0, 400, UIScreen.MainScreen.Bounds.Size.Width, 300));
UIImage image = new UIImage("th.jpg");
imageView.Image = CropImage(image, new CGRect(0, 0, 1920, 1080), 1);
View.AddSubview(imageView);

CropImage方法:

    private UIImage CropImage(UIImage image, CGRect rect, float scale)
{
    var drawRect = new CGRect(rect.X, rect.Y, rect.Size.Width, rect.Size.Height);
    using (var cgImage = image.CGImage.WithImageInRect(drawRect))
    {
        if(null != cgImage)
        {
            var croppedImage = UIImage.FromImage(cgImage);
            return croppedImage;
        }
        else
        {
            return image;
        }

    };
}

这将显示图像的原始大小:

enter image description here

现在您可以按如下方式修改裁剪的大小:

UIImageView imageView = new UIImageView(new CGRect(0, 400, UIScreen.MainScreen.Bounds.Size.Width, 300));
UIImage image = new UIImage("th.jpg");
imageView.Image = CropImage(image, new CGRect(0, 0, 1920, 100), 1);
View.AddSubview(imageView);

这里我将x = 0y = 0设置为从(0,0)开始,宽度为1920,高度为100。我只是裁剪原始图像的高度。效果如下:

enter image description here

然后如果您修改x/y,则裁剪的图像将移动到其他区域进行裁剪。如下:

UIImageView imageView = new UIImageView(new CGRect(0, 400, UIScreen.MainScreen.Bounds.Size.Width, 300));
UIImage image = new UIImage("th.jpg");
imageView.Image = CropImage(image, new CGRect(0, 100, 1920, 100), 1);
View.AddSubview(imageView);

然后您会看到第二种效果不同:

enter image description here

因此,在裁剪图像时,您应该清楚地了解drawRectimage.CGImage.WithImageInRect(drawRect)

[Note from doc:

即使UIImageView仅显示缩放版本,也必须指定相对于原始图像完整尺寸的子矩形的坐标。


0
投票

[对于发现此问题的其他人,问题似乎是在裁剪图像时CGImage旋转,导致VNRectangleObservation不再对齐。我使用本文Tracking and Altering Images来使用CIFilter获得可行的解决方案。裁剪代码如下:

var ciFilter = CIFilter.FromName("CIPerspectiveCorrection");
if (ciFilter == null) continue;

var width = inputImage.Extent.Width;
var height = inputImage.Extent.Height;
var topLeft = new CGPoint(observation.TopLeft.X * width, observation.TopLeft.Y * height);
var topRight = new CGPoint(observation.TopRight.X * width, observation.TopRight.Y * height);
var bottomLeft = new CGPoint(observation.BottomLeft.X * width, observation.BottomLeft.Y * height);
var bottomRight = new CGPoint(observation.BottomRight.X * width, observation.BottomRight.Y * height);

ciFilter.SetValueForKey(new CIVector(topLeft), new NSString("inputTopLeft"));
ciFilter.SetValueForKey(new CIVector(topRight), new NSString("inputTopRight"));
ciFilter.SetValueForKey(new CIVector(bottomLeft), new NSString("inputBottomLeft"));
ciFilter.SetValueForKey(new CIVector(bottomRight), new NSString("inputBottomRight"));

var ciImage = inputImage.CreateByApplyingOrientation(CGImagePropertyOrientation.Up);
ciFilter.SetValueForKey(ciImage, CIFilterInputKey.Image);
var outputImage = ciFilter.OutputImage;
var uiImage = new UIImage(outputImage);
imageList.Add(uiImage);

[imageListList<UImage>,因为我正在处理多个检测到的矩形。

observation是类型为VNRectangleObservation的单个观察值。

© www.soinside.com 2019 - 2024. All rights reserved.