2

我正在使用一个Go 包(Go 绑定到 ImageMagick 的 MagickWand C API)到 ImageMagick,我正在从图像中删除边框(裁剪)。我使用修剪功能的方式可以在下面找到。

现在的问题是模糊因素。例如,如果我将值设置为 2000,图像(这里是源)仍然有一些像这样的白色图像:

  • 模糊因子值 2000 -->结果
  • 模糊因子值 10000 -->结果

我创建了一个小 html 来最好地说明问题。它包含两个图像:https ://dl.dropboxusercontent.com/u/15684927/image-trim-problem.html

如您所见,源在右下角有一些像素,这会导致问题。如果我将因子设置为 10000,恐怕我会在其他图片上丢失像素。如果我将其设置为 2000,则在此类图片中修剪不正确。

所以我的实际问题是:“裁剪”/“修剪”图像的最佳方法是什么?

package main

import "gopkg.in/gographics/imagick.v1/imagick"

func main() {
    imagick.Initialize()
    defer imagick.Terminate()

    inputFile := "tshirt-original.jpg"
    outputFile := "trimmed.jpg"
    mw := imagick.NewMagickWand()
    // Schedule cleanup
    defer mw.Destroy()

    // read image
    err := mw.ReadImage(inputFile)
    if err != nil {
        panic(err)
    }

    // first trim original image
    // fuzz: by default target must match a particular pixel color exactly.
    // However, in many cases two colors may differ by a small amount. The fuzz
    // member of image defines how much tolerance is acceptable to consider two
    // colors as the same. For example, set fuzz to 10 and the color red at
    // intensities of 100 and 102 respectively are now interpreted as the same
    // color for the purposes of the floodfill.
    mw.TrimImage(10000)

    // Set the compression quality to 95 (high quality = low compression)
    err = mw.SetImageCompressionQuality(95)
    if err != nil {
        panic(err)
    }

    // save
    err = mw.WriteImage(outputFile)
    if err != nil {
        panic(err)
    }
}
4

1 回答 1

7

基本上,您的问题是您的图像边缘有一个高频、高幅度的伪影。或者,换句话说,边缘处有一个尖锐的高峰值,如果你想使用修剪,它会迫使你使用如此高的模糊值来克服这个问题,算法也认为“实际内容”是相等的到“背景”(边界)。

这里的一种解决方案是使用多步骤方法,首先平滑边缘伪影,然后对生成的图像应用修剪。通过平滑它,您可以摆脱高峰并将其涂抹在一个漂亮的连绵起伏的山丘上。反过来,起伏的丘陵可以很容易地用低模糊值修剪。然后,这将为您提供所需的几何图形,您可以使用它来裁剪原始图形。

具体来说,让我们取原始图像: 原始图像

现在,让我们使用半径为 10 且 sigma 为 10 through 的模糊来平滑边缘上的脊convert original.jpg -blur 10x10 10x10.jpg,这会产生: 10x10 模糊图像

现在,您可能会注意到边缘上的伪影现在几乎消失了。

我们现在可以进行“虚拟”修剪并询问 ImageMagick 修剪的结果是什么convert 10x10.jpg -fuzz 2000 -format %@ info:,根据文档,它会为您提供“修剪边界框(没有实际修剪) ”:1326x1560+357+578%

取这些值(百分比符号除外)并将它们用于裁剪几何图形,为您提供使用裁剪命令进行转换convert original.jpg -crop 1326x1560+357+578 cropped.jpg,它为您提供:

没有噪点的裁剪图像

编辑:

现在,由于您希望将此作为代码,使用imagick,这是代码中的解决方案。它假设您将文件存储为“./data/original.jpg”并将其存储为“./data/trimmed.jpg”

package main

import (
  "fmt"

  "gopkg.in/gographics/imagick.v2/imagick"
)

func init() {
  imagick.Initialize()
}

const originalImageFilename = "data/original.jpg"

func main() {

  mw := imagick.NewMagickWand()
  err := mw.ReadImage(originalImageFilename)
  if err != nil {
    fmt.Sprint(err.Error())
    return
  }

  // Use a clone to determine what will happen
  mw2 := mw.Clone()

  mw2.BlurImage(10, 10)
  mw2.TrimImage(2000)

  _, _, xOffset, yOffset, err := mw2.GetImagePage()
  if err != nil {
    fmt.Sprint(err.Error())
    return
  }

  trimmedWidth := mw2.GetImageWidth()
  trimmedHeight := mw2.GetImageHeight()

  mw2.Destroy()

  mw.CropImage(trimmedWidth, trimmedHeight, xOffset, yOffset)

  mw.WriteImage("data/trimmed.jpg")
  mw.Destroy()
}
于 2016-08-23T09:30:30.823 回答