裁剪矩形围绕面/坐标

时间:2016-12-21 08:23:51

标签: c# image image-processing

我正在寻找一种计算矩形(x,y,宽度和高度)的方法,该矩形可用于裁剪选定面部坐标周围的图像。

我有一张图像995x1000(https://tourspider.blob.core.windows.net/img/artists/original/947a0903-9b64-42a1-8179-108bab2a9e46.jpg),面部中心位于492x325。我可以使用各种服务找到这些信息,所以即使对于图像中的多个面部,我也能找到最突出的 - 因此是单个坐标。

现在我需要从源图像(200x150,200x200和750x250)制作各种尺寸的裁剪图像。现在我似乎无法解决如何在考虑图像边缘的同时最好地计算围绕中心坐标的矩形。脸部应该在图像中尽可能中心。

即使在尝试各种服务(https://www.microsoft.com/cognitive-services/en-us/computer-vision-api)之后,结果仍然非常糟糕,因为面部主要在750x250中,有时甚至不存在。

我还尝试使用ImageProcessor(http://imageprocessor.org/)库,您可以使用它来调整大小但无法获得所需的结果。

是否有人知道如何在预定义坐标周围进行最佳裁剪?

1 个答案:

答案 0 :(得分:1)

使用Imageprocessor我创建了以下解决方案。它还不完美,但还有很长的路要走;)

public static void StoreImage(byte[] image, int destinationWidth, int destinationHeight, Point anchor)
    {
        using (var inStream = new MemoryStream(image))
        using (var imageFactory = new ImageFactory())
        {
            // Load the image in the image factory
            imageFactory.Load(inStream);

            var originalSourceWidth = imageFactory.Image.Width;
            var originalSourceHeight = imageFactory.Image.Height;

            // Resizes the image until the shortest side reaches the set given dimension. 
            // This will maintain the aspect ratio of the original image.
            imageFactory.Resize(new ResizeLayer(new Size(destinationWidth, destinationHeight), ResizeMode.Min));

            var resizedSourceWidth = imageFactory.Image.Width;
            var resizedSourceHeight = imageFactory.Image.Height;

            //Adjust anchor position
            var resizedAnchorX = anchor.X/(originalSourceWidth / resizedSourceWidth);
            var resizedAnchorY = anchor.Y/(originalSourceHeight/resizedSourceHeight);

            if (anchor.X > originalSourceWidth || anchor.Y > originalSourceHeight)
            {
                throw new Exception($"Invalid anchor point. Image: {originalSourceWidth}x{originalSourceHeight}. Anchor: {anchor.X}x{anchor.Y}.");
            }

            var cropX = resizedAnchorX - destinationWidth/2;
            if (cropX < 0)
                cropX = 0;

            var cropY = resizedAnchorY - destinationHeight/2;
            if (cropY < 0)
                cropY = 0;
            if (cropY > resizedSourceHeight)
                cropY = resizedSourceHeight;

            imageFactory
                .Crop(new Rectangle(cropX, cropY, destinationWidth, destinationHeight))
               .Save($@"{Guid.NewGuid()}.jpg");
        }

    }