2013-12-07 20:05:18 +00:00
|
|
|
/*
|
Rename import paths from camlistore.org to perkeep.org.
Part of the project renaming, issue #981.
After this, users will need to mv their $GOPATH/src/camlistore.org to
$GOPATH/src/perkeep.org. Sorry.
This doesn't yet rename the tools like camlistored, camput, camget,
camtool, etc.
Also, this only moves the lru package to internal. More will move to
internal later.
Also, this doesn't yet remove the "/pkg/" directory. That'll likely
happen later.
This updates some docs, but not all.
devcam test now passes again, even with Go 1.10 (which requires vet
checks are clean too). So a bunch of vet tests are fixed in this CL
too, and a bunch of other broken tests are now fixed (introduced from
the past week of merging the CL backlog).
Change-Id: If580db1691b5b99f8ed6195070789b1f44877dd4
2018-01-01 22:41:41 +00:00
|
|
|
Copyright 2013 The Perkeep Authors
|
2013-12-07 20:05:18 +00:00
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
package resize
|
|
|
|
|
|
|
|
import (
|
|
|
|
"flag"
|
|
|
|
"fmt"
|
|
|
|
"image"
|
|
|
|
"image/color"
|
|
|
|
"image/draw"
|
|
|
|
"image/png"
|
|
|
|
"io"
|
|
|
|
"math"
|
|
|
|
"os"
|
2015-11-23 22:16:18 +00:00
|
|
|
"os/exec"
|
2013-12-07 20:05:18 +00:00
|
|
|
"path/filepath"
|
|
|
|
"strings"
|
|
|
|
"testing"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
// psnrThreshold is the threshold over which images must match to consider
|
|
|
|
// HalveInplace equivalent to Resize. It is in terms of dB and 60-80 is
|
|
|
|
// good for RGB.
|
|
|
|
psnrThreshold = 50.0
|
|
|
|
|
2015-08-20 23:22:05 +00:00
|
|
|
// TODO(wathiede, mpl): figure out why we got an increase from ~3% to ~16% for
|
|
|
|
// YCbCr images in Go 1.5. That is, for halving vs resizing.
|
2013-12-07 20:05:18 +00:00
|
|
|
maxPixelDiffPercentage = 10
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
2015-11-23 22:16:18 +00:00
|
|
|
flagOutput = flag.String("output", "", "If non-empty, the directory to save comparison images.")
|
|
|
|
flagUseIM = flag.Bool("imagemagick", false, "Use ImageMagick's compare as well to compute the PSNR and create the diff (for some tests)")
|
2013-12-07 20:05:18 +00:00
|
|
|
|
|
|
|
orig = image.Rect(0, 0, 1024, 1024)
|
|
|
|
thumb = image.Rect(0, 0, 64, 64)
|
|
|
|
)
|
|
|
|
|
2013-12-16 18:19:55 +00:00
|
|
|
var somePalette = []color.Color{
|
2014-03-20 19:29:45 +00:00
|
|
|
color.RGBA{0x00, 0x00, 0x00, 0xff},
|
|
|
|
color.RGBA{0x00, 0x00, 0x44, 0xff},
|
|
|
|
color.RGBA{0x00, 0x00, 0x88, 0xff},
|
|
|
|
color.RGBA{0x00, 0x00, 0xcc, 0xff},
|
|
|
|
color.RGBA{0x00, 0x44, 0x00, 0xff},
|
|
|
|
color.RGBA{0x00, 0x44, 0x44, 0xff},
|
|
|
|
color.RGBA{0x00, 0x44, 0x88, 0xff},
|
|
|
|
color.RGBA{0x00, 0x44, 0xcc, 0xff},
|
2013-12-16 18:19:55 +00:00
|
|
|
}
|
|
|
|
|
2013-12-07 20:05:18 +00:00
|
|
|
func makeImages(r image.Rectangle) []image.Image {
|
|
|
|
return []image.Image{
|
|
|
|
image.NewGray(r),
|
|
|
|
image.NewGray16(r),
|
|
|
|
image.NewNRGBA(r),
|
|
|
|
image.NewNRGBA64(r),
|
2013-12-16 18:19:55 +00:00
|
|
|
image.NewPaletted(r, somePalette),
|
2013-12-07 20:05:18 +00:00
|
|
|
image.NewRGBA(r),
|
|
|
|
image.NewRGBA64(r),
|
|
|
|
image.NewYCbCr(r, image.YCbCrSubsampleRatio444),
|
|
|
|
image.NewYCbCr(r, image.YCbCrSubsampleRatio422),
|
|
|
|
image.NewYCbCr(r, image.YCbCrSubsampleRatio420),
|
|
|
|
image.NewYCbCr(r, image.YCbCrSubsampleRatio440),
|
2015-08-20 23:22:05 +00:00
|
|
|
image.NewYCbCr(r, image.YCbCrSubsampleRatio410),
|
|
|
|
image.NewYCbCr(r, image.YCbCrSubsampleRatio411),
|
2013-12-07 20:05:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestResize(t *testing.T) {
|
|
|
|
for i, im := range makeImages(orig) {
|
|
|
|
m := Resize(im, orig, thumb.Dx(), thumb.Dy())
|
|
|
|
got, want := m.Bounds(), thumb
|
|
|
|
if !got.Eq(want) {
|
|
|
|
t.Error(i, "Want bounds", want, "got", got)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestResampleInplace(t *testing.T) {
|
|
|
|
for i, im := range makeImages(orig) {
|
|
|
|
m := ResampleInplace(im, orig, thumb.Dx(), thumb.Dy())
|
|
|
|
got, want := m.Bounds(), thumb
|
|
|
|
if !got.Eq(want) {
|
|
|
|
t.Error(i, "Want bounds", want, "got", got)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestResample(t *testing.T) {
|
|
|
|
for i, im := range makeImages(orig) {
|
|
|
|
m := Resample(im, orig, thumb.Dx(), thumb.Dy())
|
|
|
|
got, want := m.Bounds(), thumb
|
|
|
|
if !got.Eq(want) {
|
|
|
|
t.Error(i, "Want bounds", want, "got", got)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, d := range []struct {
|
|
|
|
wantFn string
|
|
|
|
r image.Rectangle
|
|
|
|
w, h int
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
// Generated with imagemagick:
|
|
|
|
// $ convert -crop 128x128+320+160 -resize 64x64 -filter point \
|
|
|
|
// testdata/test.png testdata/test-resample-128x128-64x64.png
|
|
|
|
wantFn: "test-resample-128x128-64x64.png",
|
|
|
|
r: image.Rect(320, 160, 320+128, 160+128),
|
|
|
|
w: 64,
|
|
|
|
h: 64,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
// Generated with imagemagick:
|
|
|
|
// $ convert -resize 128x128 -filter point testdata/test.png \
|
|
|
|
// testdata/test-resample-768x576-128x96.png
|
|
|
|
wantFn: "test-resample-768x576-128x96.png",
|
|
|
|
r: image.Rect(0, 0, 768, 576),
|
|
|
|
w: 128,
|
|
|
|
h: 96,
|
|
|
|
},
|
|
|
|
} {
|
|
|
|
m := image.NewRGBA(testIm.Bounds())
|
|
|
|
fillTestImage(m)
|
|
|
|
r, err := os.Open(filepath.Join("testdata", d.wantFn))
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
defer r.Close()
|
|
|
|
want, err := png.Decode(r)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
got := Resample(m, d.r, d.w, d.h)
|
2015-11-23 22:16:18 +00:00
|
|
|
res := compareImages(got, want, false)
|
2013-12-07 20:05:18 +00:00
|
|
|
t.Logf("PSNR %.4f", res.psnr)
|
|
|
|
s := got.Bounds().Size()
|
|
|
|
tot := s.X * s.Y
|
|
|
|
per := float32(100*res.diffCnt) / float32(tot)
|
|
|
|
t.Logf("Resample not the same %d pixels different %.2f%%", res.diffCnt, per)
|
2015-11-23 22:16:18 +00:00
|
|
|
if *flagOutput != "" {
|
2013-12-07 20:05:18 +00:00
|
|
|
err = savePng(t, want, fmt.Sprintf("Resample.%s->%dx%d.want.png",
|
|
|
|
d.r, d.w, d.h))
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
err = savePng(t, got, fmt.Sprintf("Resample.%s->%dx%d.got.png",
|
|
|
|
d.r, d.w, d.h))
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
err = savePng(t, res.diffIm,
|
|
|
|
fmt.Sprintf("Resample.%s->%dx%d.diff.png", d.r, d.w, d.h))
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestHalveInplace(t *testing.T) {
|
|
|
|
for i, im := range makeImages(orig) {
|
|
|
|
m := HalveInplace(im)
|
|
|
|
b := im.Bounds()
|
|
|
|
got, want := m.Bounds(), image.Rectangle{
|
|
|
|
Min: b.Min,
|
|
|
|
Max: b.Min.Add(b.Max.Div(2)),
|
|
|
|
}
|
|
|
|
if !got.Eq(want) {
|
|
|
|
t.Error(i, "Want bounds", want, "got", got)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
type results struct {
|
|
|
|
diffCnt int
|
|
|
|
psnr float64
|
|
|
|
diffIm *image.Gray
|
|
|
|
}
|
|
|
|
|
2015-11-23 22:16:18 +00:00
|
|
|
// if halfSize, m1 has to be 2*m2
|
|
|
|
func compareImages(m1, m2 image.Image, halfSize bool) results {
|
|
|
|
b := m2.Bounds()
|
2013-12-07 20:05:18 +00:00
|
|
|
s := b.Size()
|
|
|
|
res := results{}
|
|
|
|
mse := uint32(0)
|
|
|
|
for y := b.Min.Y; y < b.Max.Y; y++ {
|
|
|
|
for x := b.Min.X; x < b.Max.X; x++ {
|
2015-11-23 22:16:18 +00:00
|
|
|
var r1, g1, b1, a1 uint32
|
|
|
|
if halfSize {
|
|
|
|
r1, g1, b1, a1 = m1.At(x*2, y*2).RGBA()
|
|
|
|
} else {
|
|
|
|
r1, g1, b1, a1 = m1.At(x, y).RGBA()
|
|
|
|
}
|
2013-12-07 20:05:18 +00:00
|
|
|
r2, g2, b2, a2 := m2.At(x, y).RGBA()
|
|
|
|
mse += ((r1-r2)*(r1-r2) + (g1-g2)*(g1-g2) + (b1-b2)*(b1-b2)) / 3
|
|
|
|
if r1 != r2 || g1 != g2 || b1 != b2 || a1 != a2 {
|
|
|
|
if res.diffIm == nil {
|
|
|
|
res.diffIm = image.NewGray(m1.Bounds())
|
|
|
|
}
|
|
|
|
res.diffCnt++
|
|
|
|
res.diffIm.Set(x, y, color.White)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
mse = mse / uint32(s.X*s.Y)
|
|
|
|
res.psnr = 20*math.Log10(1<<16) - 10*math.Log10(float64(mse))
|
|
|
|
return res
|
|
|
|
}
|
|
|
|
|
|
|
|
var testIm image.Image
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
r, err := os.Open(filepath.Join("testdata", "test.png"))
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
defer r.Close()
|
|
|
|
testIm, err = png.Decode(r)
|
|
|
|
}
|
|
|
|
|
|
|
|
func fillTestImage(im image.Image) {
|
|
|
|
b := im.Bounds()
|
|
|
|
if !b.Eq(testIm.Bounds()) {
|
|
|
|
panic("Requested target image dimensions not equal reference image.")
|
|
|
|
}
|
|
|
|
src := testIm
|
|
|
|
if dst, ok := im.(*image.YCbCr); ok {
|
|
|
|
b := testIm.Bounds()
|
|
|
|
for y := b.Min.Y; y < b.Max.Y; y++ {
|
|
|
|
for x := b.Min.X; x < b.Max.X; x++ {
|
|
|
|
r, g, b, _ := src.At(x, y).RGBA()
|
|
|
|
yp, cb, cr := color.RGBToYCbCr(uint8(r), uint8(g), uint8(b))
|
|
|
|
|
|
|
|
dst.Y[dst.YOffset(x, y)] = yp
|
|
|
|
off := dst.COffset(x, y)
|
|
|
|
dst.Cb[off] = cb
|
|
|
|
dst.Cr[off] = cr
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
draw.Draw(im.(draw.Image), b, testIm, b.Min, draw.Src)
|
|
|
|
}
|
|
|
|
|
|
|
|
func savePng(t *testing.T, m image.Image, fn string) error {
|
2015-11-23 22:16:18 +00:00
|
|
|
fn = filepath.Join(*flagOutput, fn)
|
2013-12-07 20:05:18 +00:00
|
|
|
t.Log("Saving", fn)
|
|
|
|
f, err := os.Create(fn)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer f.Close()
|
|
|
|
|
|
|
|
return png.Encode(f, m)
|
|
|
|
}
|
|
|
|
|
2015-11-20 20:40:22 +00:00
|
|
|
func getFilename(imType string, method string) string {
|
|
|
|
return fmt.Sprintf("%s.%s.png", imType, method)
|
2013-12-07 20:05:18 +00:00
|
|
|
}
|
|
|
|
|
2015-09-04 23:03:09 +00:00
|
|
|
func TestCompareResizeToHalveInplace(t *testing.T) {
|
2015-11-23 22:16:18 +00:00
|
|
|
t.Skip("Skipping TestCompareResizeToHalveInplace until we know better why resizing YCbCr leads to so many differences.")
|
2018-01-06 03:49:59 +00:00
|
|
|
// Here is what I found out so far, while investigating https://github.com/perkeep/perkeep/issues/635:
|
2015-11-23 22:16:18 +00:00
|
|
|
// 1) Using imagemagick to compute the PSNR yields (significantly) different results (from
|
|
|
|
// the manually computed one in compareImages) for YCbCr images. It is even worse with
|
|
|
|
// imagemagick most of the time. It would be interesting to know why.
|
|
|
|
// 2) When the diff is generated with imagemagick, we see the difference for each channel,
|
|
|
|
// not just in absolute. And it seems that the main distortion is in the red, beats me.
|
|
|
|
// 3) TestCompareOriginalToHalveInPlace vs TestCompareOriginalToResized seems to indicate
|
|
|
|
// that we're getting more difference (as far as pixel count goes, not in PSNR) when resizing
|
|
|
|
// than when halving in place, which is troubling. Furthermore, the diffs generated by
|
|
|
|
// TestCompareResizeToHalveInplace looks more similar to TestCompareOriginalToResized than
|
|
|
|
// TestCompareOriginalToHalveInPlace, so it looks to me like resizing is the main contributor
|
|
|
|
// to the difference we see between resizing and halving.
|
|
|
|
// 4) Nevertheless, since both TestCompareOriginalToResized and
|
|
|
|
// TestCompareOriginalToHalveInPlace both still (barely) pass, I think it's ok to disable
|
|
|
|
// TestCompareResizeToHalveInplace until we know more.
|
|
|
|
// 5) If it turns out in the end that there was nothing to worry about, then maybe we could
|
2017-09-10 13:28:34 +00:00
|
|
|
// have this test pass, not by lowering the maxPixelDiffPercentage, but by introducing a
|
2015-11-23 22:16:18 +00:00
|
|
|
// tolerance such as http://www.imagemagick.org/script/command-line-options.php#fuzz when
|
|
|
|
// comparing the pixels.
|
pkg/images/resize: show that golang.org/x/image/draw is a win
While investigating issue #635 I remembered that golang.org/x/image/draw
might offer some interesting features. It indeed happens to have some
rescaling routines that seem to work better in the YCbCr case than our
custom code, which is illustrated by these benchmarks:
% go test -v -bench Benchmark.*YCrCb.* -run Bench* -benchmem
% ./pkg/images/resize/
PASS
BenchmarkResizeYCrCb-4 20 79213653 ns/op
9437475 B/op 5 allocs/op
BenchmarkNewResizeYCrCb-4 100 15711294 ns/op
1048668 B/op 2 allocs/op
BenchmarkHalveYCrCb-4 100 17328467 ns/op
128 B/op 1 allocs/op
ok camlistore.org/pkg/images/resize 5.889s
One can see that not only the new resize is faster, and uses less memory
than the old one, but it is also about as fast as "resizing by halving
in place". And this is with the ApproxBiLinear algorithm; some quick
additional tests seemed to indicate that NearestNeighbor was twice as
fast, with about the same memory usage. I chose ApproxBiLinear as it
seemed the most conservative choice for now.
I think it is also worth investigating whether we can be rid of "halving
in place", since it would make for simpler code overall, and since
ApproxBiLinear might be faster in most cases. It would have the nice
side-effect of solving issue #635 too. However, "halving in place" will
always win when it comes to memory usage, so it depends on our
priorities.
Finally, these other new benchmarks show that using the new resize does
not make the #635 mystery much worse (going from ~16% to ~18%), and that
interestingly the results of the old resize and the new resize are
pretty different by themselves.
% go test -v -run TestCompare ./pkg/images/resize/
=== RUN TestCompareOldResizeToHalveInplace
--- FAIL: TestCompareOldResizeToHalveInplace (2.49s)
resize_test.go:377: *image.Gray PSNR 63.7793
resize_test.go:377: *image.Gray16 PSNR 59.9547
resize_test.go:377: *image.NRGBA PSNR 62.8252
resize_test.go:377: *image.NRGBA64 PSNR 62.8252
resize_test.go:377: *image.Paletted PSNR 51.4949
resize_test.go:377: *image.RGBA PSNR 62.8252
resize_test.go:377: *image.RGBA64 PSNR 62.8252
resize_test.go:377: *image.YCbCr PSNR 61.9664
resize_test.go:382: *image.YCbCr not the same 18077 pixels
different 16.35%
resize_test.go:377: *image.YCbCr PSNR 52.4121
resize_test.go:382: *image.YCbCr not the same 18139 pixels
different 16.40%
resize_test.go:377: *image.YCbCr PSNR 51.4972
resize_test.go:382: *image.YCbCr not the same 17932 pixels
different 16.21%
resize_test.go:377: *image.YCbCr PSNR 51.6399
resize_test.go:382: *image.YCbCr not the same 17881 pixels
different 16.17%
resize_test.go:377: *image.YCbCr PSNR 50.7736
resize_test.go:382: *image.YCbCr not the same 17976 pixels
different 16.25%
resize_test.go:377: *image.YCbCr PSNR 52.4536
resize_test.go:382: *image.YCbCr not the same 18180 pixels
different 16.44%
=== RUN TestCompareNewResizeToHalveInplace
--- FAIL: TestCompareNewResizeToHalveInplace (2.27s)
resize_test.go:377: *image.Gray PSNR 63.7793
resize_test.go:377: *image.Gray16 PSNR 59.9547
resize_test.go:377: *image.NRGBA PSNR 62.8252
resize_test.go:377: *image.NRGBA64 PSNR 62.8252
resize_test.go:377: *image.Paletted PSNR 51.4949
resize_test.go:377: *image.RGBA PSNR 62.8252
resize_test.go:377: *image.RGBA64 PSNR 62.8252
resize_test.go:377: *image.YCbCr PSNR 59.5902
resize_test.go:382: *image.YCbCr not the same 20757 pixels
different 18.77%
resize_test.go:377: *image.YCbCr PSNR 52.0962
resize_test.go:382: *image.YCbCr not the same 20811 pixels
different 18.82%
resize_test.go:377: *image.YCbCr PSNR 51.3374
resize_test.go:382: *image.YCbCr not the same 20671 pixels
different 18.69%
resize_test.go:377: *image.YCbCr PSNR 51.3586
resize_test.go:382: *image.YCbCr not the same 20618 pixels
different 18.64%
resize_test.go:377: *image.YCbCr PSNR 57.2346
resize_test.go:382: *image.YCbCr not the same 20705 pixels
different 18.72%
resize_test.go:377: *image.YCbCr PSNR 50.7504
resize_test.go:382: *image.YCbCr not the same 20847 pixels
different 18.85%
=== RUN TestCompareOldResizeToNewResize
--- FAIL: TestCompareOldResizeToNewResize (2.54s)
resize_test.go:377: *image.Gray PSNR +Inf
resize_test.go:377: *image.Gray16 PSNR +Inf
resize_test.go:377: *image.NRGBA PSNR +Inf
resize_test.go:377: *image.NRGBA64 PSNR +Inf
resize_test.go:377: *image.Paletted PSNR +Inf
resize_test.go:377: *image.RGBA PSNR +Inf
resize_test.go:377: *image.RGBA64 PSNR +Inf
resize_test.go:377: *image.YCbCr PSNR 59.1024
resize_test.go:382: *image.YCbCr not the same 16350 pixels
different 14.78%
resize_test.go:377: *image.YCbCr PSNR 62.6523
resize_test.go:377: *image.YCbCr PSNR 62.7010
resize_test.go:377: *image.YCbCr PSNR 59.1396
resize_test.go:382: *image.YCbCr not the same 16225 pixels
different 14.67%
resize_test.go:377: *image.YCbCr PSNR 59.0844
resize_test.go:382: *image.YCbCr not the same 16294 pixels
different 14.73%
resize_test.go:377: *image.YCbCr PSNR 59.0534
resize_test.go:382: *image.YCbCr not the same 16413 pixels
different 14.84%
Change-Id: Ia8c578a53416ec0f1cac1477a1a68acfede84b24
2015-09-04 22:54:31 +00:00
|
|
|
if testing.Short() {
|
|
|
|
t.Skip("Skipping TestCompareNewResizeToHalveInplace in short mode.")
|
|
|
|
}
|
2015-09-04 23:03:09 +00:00
|
|
|
testCompareResizeMethods(t, "resize", "halveInPlace")
|
pkg/images/resize: show that golang.org/x/image/draw is a win
While investigating issue #635 I remembered that golang.org/x/image/draw
might offer some interesting features. It indeed happens to have some
rescaling routines that seem to work better in the YCbCr case than our
custom code, which is illustrated by these benchmarks:
% go test -v -bench Benchmark.*YCrCb.* -run Bench* -benchmem
% ./pkg/images/resize/
PASS
BenchmarkResizeYCrCb-4 20 79213653 ns/op
9437475 B/op 5 allocs/op
BenchmarkNewResizeYCrCb-4 100 15711294 ns/op
1048668 B/op 2 allocs/op
BenchmarkHalveYCrCb-4 100 17328467 ns/op
128 B/op 1 allocs/op
ok camlistore.org/pkg/images/resize 5.889s
One can see that not only the new resize is faster, and uses less memory
than the old one, but it is also about as fast as "resizing by halving
in place". And this is with the ApproxBiLinear algorithm; some quick
additional tests seemed to indicate that NearestNeighbor was twice as
fast, with about the same memory usage. I chose ApproxBiLinear as it
seemed the most conservative choice for now.
I think it is also worth investigating whether we can be rid of "halving
in place", since it would make for simpler code overall, and since
ApproxBiLinear might be faster in most cases. It would have the nice
side-effect of solving issue #635 too. However, "halving in place" will
always win when it comes to memory usage, so it depends on our
priorities.
Finally, these other new benchmarks show that using the new resize does
not make the #635 mystery much worse (going from ~16% to ~18%), and that
interestingly the results of the old resize and the new resize are
pretty different by themselves.
% go test -v -run TestCompare ./pkg/images/resize/
=== RUN TestCompareOldResizeToHalveInplace
--- FAIL: TestCompareOldResizeToHalveInplace (2.49s)
resize_test.go:377: *image.Gray PSNR 63.7793
resize_test.go:377: *image.Gray16 PSNR 59.9547
resize_test.go:377: *image.NRGBA PSNR 62.8252
resize_test.go:377: *image.NRGBA64 PSNR 62.8252
resize_test.go:377: *image.Paletted PSNR 51.4949
resize_test.go:377: *image.RGBA PSNR 62.8252
resize_test.go:377: *image.RGBA64 PSNR 62.8252
resize_test.go:377: *image.YCbCr PSNR 61.9664
resize_test.go:382: *image.YCbCr not the same 18077 pixels
different 16.35%
resize_test.go:377: *image.YCbCr PSNR 52.4121
resize_test.go:382: *image.YCbCr not the same 18139 pixels
different 16.40%
resize_test.go:377: *image.YCbCr PSNR 51.4972
resize_test.go:382: *image.YCbCr not the same 17932 pixels
different 16.21%
resize_test.go:377: *image.YCbCr PSNR 51.6399
resize_test.go:382: *image.YCbCr not the same 17881 pixels
different 16.17%
resize_test.go:377: *image.YCbCr PSNR 50.7736
resize_test.go:382: *image.YCbCr not the same 17976 pixels
different 16.25%
resize_test.go:377: *image.YCbCr PSNR 52.4536
resize_test.go:382: *image.YCbCr not the same 18180 pixels
different 16.44%
=== RUN TestCompareNewResizeToHalveInplace
--- FAIL: TestCompareNewResizeToHalveInplace (2.27s)
resize_test.go:377: *image.Gray PSNR 63.7793
resize_test.go:377: *image.Gray16 PSNR 59.9547
resize_test.go:377: *image.NRGBA PSNR 62.8252
resize_test.go:377: *image.NRGBA64 PSNR 62.8252
resize_test.go:377: *image.Paletted PSNR 51.4949
resize_test.go:377: *image.RGBA PSNR 62.8252
resize_test.go:377: *image.RGBA64 PSNR 62.8252
resize_test.go:377: *image.YCbCr PSNR 59.5902
resize_test.go:382: *image.YCbCr not the same 20757 pixels
different 18.77%
resize_test.go:377: *image.YCbCr PSNR 52.0962
resize_test.go:382: *image.YCbCr not the same 20811 pixels
different 18.82%
resize_test.go:377: *image.YCbCr PSNR 51.3374
resize_test.go:382: *image.YCbCr not the same 20671 pixels
different 18.69%
resize_test.go:377: *image.YCbCr PSNR 51.3586
resize_test.go:382: *image.YCbCr not the same 20618 pixels
different 18.64%
resize_test.go:377: *image.YCbCr PSNR 57.2346
resize_test.go:382: *image.YCbCr not the same 20705 pixels
different 18.72%
resize_test.go:377: *image.YCbCr PSNR 50.7504
resize_test.go:382: *image.YCbCr not the same 20847 pixels
different 18.85%
=== RUN TestCompareOldResizeToNewResize
--- FAIL: TestCompareOldResizeToNewResize (2.54s)
resize_test.go:377: *image.Gray PSNR +Inf
resize_test.go:377: *image.Gray16 PSNR +Inf
resize_test.go:377: *image.NRGBA PSNR +Inf
resize_test.go:377: *image.NRGBA64 PSNR +Inf
resize_test.go:377: *image.Paletted PSNR +Inf
resize_test.go:377: *image.RGBA PSNR +Inf
resize_test.go:377: *image.RGBA64 PSNR +Inf
resize_test.go:377: *image.YCbCr PSNR 59.1024
resize_test.go:382: *image.YCbCr not the same 16350 pixels
different 14.78%
resize_test.go:377: *image.YCbCr PSNR 62.6523
resize_test.go:377: *image.YCbCr PSNR 62.7010
resize_test.go:377: *image.YCbCr PSNR 59.1396
resize_test.go:382: *image.YCbCr not the same 16225 pixels
different 14.67%
resize_test.go:377: *image.YCbCr PSNR 59.0844
resize_test.go:382: *image.YCbCr not the same 16294 pixels
different 14.73%
resize_test.go:377: *image.YCbCr PSNR 59.0534
resize_test.go:382: *image.YCbCr not the same 16413 pixels
different 14.84%
Change-Id: Ia8c578a53416ec0f1cac1477a1a68acfede84b24
2015-09-04 22:54:31 +00:00
|
|
|
}
|
|
|
|
|
2015-11-23 22:16:18 +00:00
|
|
|
func TestCompareOriginalToHalveInPlace(t *testing.T) {
|
|
|
|
if testing.Short() {
|
|
|
|
t.Skip("Skipping TestCompareOriginalToHalveInPlace in short mode.")
|
|
|
|
}
|
|
|
|
testCompareWithResized(t, "halveInPlace")
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestCompareOriginalToResized(t *testing.T) {
|
|
|
|
if testing.Short() {
|
|
|
|
t.Skip("Skipping TestCompareOriginalToResized in short mode.")
|
|
|
|
}
|
|
|
|
testCompareWithResized(t, "resize")
|
|
|
|
}
|
|
|
|
|
pkg/images/resize: show that golang.org/x/image/draw is a win
While investigating issue #635 I remembered that golang.org/x/image/draw
might offer some interesting features. It indeed happens to have some
rescaling routines that seem to work better in the YCbCr case than our
custom code, which is illustrated by these benchmarks:
% go test -v -bench Benchmark.*YCrCb.* -run Bench* -benchmem
% ./pkg/images/resize/
PASS
BenchmarkResizeYCrCb-4 20 79213653 ns/op
9437475 B/op 5 allocs/op
BenchmarkNewResizeYCrCb-4 100 15711294 ns/op
1048668 B/op 2 allocs/op
BenchmarkHalveYCrCb-4 100 17328467 ns/op
128 B/op 1 allocs/op
ok camlistore.org/pkg/images/resize 5.889s
One can see that not only the new resize is faster, and uses less memory
than the old one, but it is also about as fast as "resizing by halving
in place". And this is with the ApproxBiLinear algorithm; some quick
additional tests seemed to indicate that NearestNeighbor was twice as
fast, with about the same memory usage. I chose ApproxBiLinear as it
seemed the most conservative choice for now.
I think it is also worth investigating whether we can be rid of "halving
in place", since it would make for simpler code overall, and since
ApproxBiLinear might be faster in most cases. It would have the nice
side-effect of solving issue #635 too. However, "halving in place" will
always win when it comes to memory usage, so it depends on our
priorities.
Finally, these other new benchmarks show that using the new resize does
not make the #635 mystery much worse (going from ~16% to ~18%), and that
interestingly the results of the old resize and the new resize are
pretty different by themselves.
% go test -v -run TestCompare ./pkg/images/resize/
=== RUN TestCompareOldResizeToHalveInplace
--- FAIL: TestCompareOldResizeToHalveInplace (2.49s)
resize_test.go:377: *image.Gray PSNR 63.7793
resize_test.go:377: *image.Gray16 PSNR 59.9547
resize_test.go:377: *image.NRGBA PSNR 62.8252
resize_test.go:377: *image.NRGBA64 PSNR 62.8252
resize_test.go:377: *image.Paletted PSNR 51.4949
resize_test.go:377: *image.RGBA PSNR 62.8252
resize_test.go:377: *image.RGBA64 PSNR 62.8252
resize_test.go:377: *image.YCbCr PSNR 61.9664
resize_test.go:382: *image.YCbCr not the same 18077 pixels
different 16.35%
resize_test.go:377: *image.YCbCr PSNR 52.4121
resize_test.go:382: *image.YCbCr not the same 18139 pixels
different 16.40%
resize_test.go:377: *image.YCbCr PSNR 51.4972
resize_test.go:382: *image.YCbCr not the same 17932 pixels
different 16.21%
resize_test.go:377: *image.YCbCr PSNR 51.6399
resize_test.go:382: *image.YCbCr not the same 17881 pixels
different 16.17%
resize_test.go:377: *image.YCbCr PSNR 50.7736
resize_test.go:382: *image.YCbCr not the same 17976 pixels
different 16.25%
resize_test.go:377: *image.YCbCr PSNR 52.4536
resize_test.go:382: *image.YCbCr not the same 18180 pixels
different 16.44%
=== RUN TestCompareNewResizeToHalveInplace
--- FAIL: TestCompareNewResizeToHalveInplace (2.27s)
resize_test.go:377: *image.Gray PSNR 63.7793
resize_test.go:377: *image.Gray16 PSNR 59.9547
resize_test.go:377: *image.NRGBA PSNR 62.8252
resize_test.go:377: *image.NRGBA64 PSNR 62.8252
resize_test.go:377: *image.Paletted PSNR 51.4949
resize_test.go:377: *image.RGBA PSNR 62.8252
resize_test.go:377: *image.RGBA64 PSNR 62.8252
resize_test.go:377: *image.YCbCr PSNR 59.5902
resize_test.go:382: *image.YCbCr not the same 20757 pixels
different 18.77%
resize_test.go:377: *image.YCbCr PSNR 52.0962
resize_test.go:382: *image.YCbCr not the same 20811 pixels
different 18.82%
resize_test.go:377: *image.YCbCr PSNR 51.3374
resize_test.go:382: *image.YCbCr not the same 20671 pixels
different 18.69%
resize_test.go:377: *image.YCbCr PSNR 51.3586
resize_test.go:382: *image.YCbCr not the same 20618 pixels
different 18.64%
resize_test.go:377: *image.YCbCr PSNR 57.2346
resize_test.go:382: *image.YCbCr not the same 20705 pixels
different 18.72%
resize_test.go:377: *image.YCbCr PSNR 50.7504
resize_test.go:382: *image.YCbCr not the same 20847 pixels
different 18.85%
=== RUN TestCompareOldResizeToNewResize
--- FAIL: TestCompareOldResizeToNewResize (2.54s)
resize_test.go:377: *image.Gray PSNR +Inf
resize_test.go:377: *image.Gray16 PSNR +Inf
resize_test.go:377: *image.NRGBA PSNR +Inf
resize_test.go:377: *image.NRGBA64 PSNR +Inf
resize_test.go:377: *image.Paletted PSNR +Inf
resize_test.go:377: *image.RGBA PSNR +Inf
resize_test.go:377: *image.RGBA64 PSNR +Inf
resize_test.go:377: *image.YCbCr PSNR 59.1024
resize_test.go:382: *image.YCbCr not the same 16350 pixels
different 14.78%
resize_test.go:377: *image.YCbCr PSNR 62.6523
resize_test.go:377: *image.YCbCr PSNR 62.7010
resize_test.go:377: *image.YCbCr PSNR 59.1396
resize_test.go:382: *image.YCbCr not the same 16225 pixels
different 14.67%
resize_test.go:377: *image.YCbCr PSNR 59.0844
resize_test.go:382: *image.YCbCr not the same 16294 pixels
different 14.73%
resize_test.go:377: *image.YCbCr PSNR 59.0534
resize_test.go:382: *image.YCbCr not the same 16413 pixels
different 14.84%
Change-Id: Ia8c578a53416ec0f1cac1477a1a68acfede84b24
2015-09-04 22:54:31 +00:00
|
|
|
var resizeMethods = map[string]func(image.Image) image.Image{
|
2015-09-04 23:03:09 +00:00
|
|
|
"resize": func(im image.Image) image.Image {
|
pkg/images/resize: show that golang.org/x/image/draw is a win
While investigating issue #635 I remembered that golang.org/x/image/draw
might offer some interesting features. It indeed happens to have some
rescaling routines that seem to work better in the YCbCr case than our
custom code, which is illustrated by these benchmarks:
% go test -v -bench Benchmark.*YCrCb.* -run Bench* -benchmem
% ./pkg/images/resize/
PASS
BenchmarkResizeYCrCb-4 20 79213653 ns/op
9437475 B/op 5 allocs/op
BenchmarkNewResizeYCrCb-4 100 15711294 ns/op
1048668 B/op 2 allocs/op
BenchmarkHalveYCrCb-4 100 17328467 ns/op
128 B/op 1 allocs/op
ok camlistore.org/pkg/images/resize 5.889s
One can see that not only the new resize is faster, and uses less memory
than the old one, but it is also about as fast as "resizing by halving
in place". And this is with the ApproxBiLinear algorithm; some quick
additional tests seemed to indicate that NearestNeighbor was twice as
fast, with about the same memory usage. I chose ApproxBiLinear as it
seemed the most conservative choice for now.
I think it is also worth investigating whether we can be rid of "halving
in place", since it would make for simpler code overall, and since
ApproxBiLinear might be faster in most cases. It would have the nice
side-effect of solving issue #635 too. However, "halving in place" will
always win when it comes to memory usage, so it depends on our
priorities.
Finally, these other new benchmarks show that using the new resize does
not make the #635 mystery much worse (going from ~16% to ~18%), and that
interestingly the results of the old resize and the new resize are
pretty different by themselves.
% go test -v -run TestCompare ./pkg/images/resize/
=== RUN TestCompareOldResizeToHalveInplace
--- FAIL: TestCompareOldResizeToHalveInplace (2.49s)
resize_test.go:377: *image.Gray PSNR 63.7793
resize_test.go:377: *image.Gray16 PSNR 59.9547
resize_test.go:377: *image.NRGBA PSNR 62.8252
resize_test.go:377: *image.NRGBA64 PSNR 62.8252
resize_test.go:377: *image.Paletted PSNR 51.4949
resize_test.go:377: *image.RGBA PSNR 62.8252
resize_test.go:377: *image.RGBA64 PSNR 62.8252
resize_test.go:377: *image.YCbCr PSNR 61.9664
resize_test.go:382: *image.YCbCr not the same 18077 pixels
different 16.35%
resize_test.go:377: *image.YCbCr PSNR 52.4121
resize_test.go:382: *image.YCbCr not the same 18139 pixels
different 16.40%
resize_test.go:377: *image.YCbCr PSNR 51.4972
resize_test.go:382: *image.YCbCr not the same 17932 pixels
different 16.21%
resize_test.go:377: *image.YCbCr PSNR 51.6399
resize_test.go:382: *image.YCbCr not the same 17881 pixels
different 16.17%
resize_test.go:377: *image.YCbCr PSNR 50.7736
resize_test.go:382: *image.YCbCr not the same 17976 pixels
different 16.25%
resize_test.go:377: *image.YCbCr PSNR 52.4536
resize_test.go:382: *image.YCbCr not the same 18180 pixels
different 16.44%
=== RUN TestCompareNewResizeToHalveInplace
--- FAIL: TestCompareNewResizeToHalveInplace (2.27s)
resize_test.go:377: *image.Gray PSNR 63.7793
resize_test.go:377: *image.Gray16 PSNR 59.9547
resize_test.go:377: *image.NRGBA PSNR 62.8252
resize_test.go:377: *image.NRGBA64 PSNR 62.8252
resize_test.go:377: *image.Paletted PSNR 51.4949
resize_test.go:377: *image.RGBA PSNR 62.8252
resize_test.go:377: *image.RGBA64 PSNR 62.8252
resize_test.go:377: *image.YCbCr PSNR 59.5902
resize_test.go:382: *image.YCbCr not the same 20757 pixels
different 18.77%
resize_test.go:377: *image.YCbCr PSNR 52.0962
resize_test.go:382: *image.YCbCr not the same 20811 pixels
different 18.82%
resize_test.go:377: *image.YCbCr PSNR 51.3374
resize_test.go:382: *image.YCbCr not the same 20671 pixels
different 18.69%
resize_test.go:377: *image.YCbCr PSNR 51.3586
resize_test.go:382: *image.YCbCr not the same 20618 pixels
different 18.64%
resize_test.go:377: *image.YCbCr PSNR 57.2346
resize_test.go:382: *image.YCbCr not the same 20705 pixels
different 18.72%
resize_test.go:377: *image.YCbCr PSNR 50.7504
resize_test.go:382: *image.YCbCr not the same 20847 pixels
different 18.85%
=== RUN TestCompareOldResizeToNewResize
--- FAIL: TestCompareOldResizeToNewResize (2.54s)
resize_test.go:377: *image.Gray PSNR +Inf
resize_test.go:377: *image.Gray16 PSNR +Inf
resize_test.go:377: *image.NRGBA PSNR +Inf
resize_test.go:377: *image.NRGBA64 PSNR +Inf
resize_test.go:377: *image.Paletted PSNR +Inf
resize_test.go:377: *image.RGBA PSNR +Inf
resize_test.go:377: *image.RGBA64 PSNR +Inf
resize_test.go:377: *image.YCbCr PSNR 59.1024
resize_test.go:382: *image.YCbCr not the same 16350 pixels
different 14.78%
resize_test.go:377: *image.YCbCr PSNR 62.6523
resize_test.go:377: *image.YCbCr PSNR 62.7010
resize_test.go:377: *image.YCbCr PSNR 59.1396
resize_test.go:382: *image.YCbCr not the same 16225 pixels
different 14.67%
resize_test.go:377: *image.YCbCr PSNR 59.0844
resize_test.go:382: *image.YCbCr not the same 16294 pixels
different 14.73%
resize_test.go:377: *image.YCbCr PSNR 59.0534
resize_test.go:382: *image.YCbCr not the same 16413 pixels
different 14.84%
Change-Id: Ia8c578a53416ec0f1cac1477a1a68acfede84b24
2015-09-04 22:54:31 +00:00
|
|
|
s := im.Bounds().Size()
|
|
|
|
return Resize(im, im.Bounds(), s.X/2, s.Y/2)
|
|
|
|
},
|
|
|
|
"halveInPlace": func(im image.Image) image.Image {
|
|
|
|
return HalveInplace(im)
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
func testCompareResizeMethods(t *testing.T, method1, method2 string) {
|
2013-12-07 20:05:18 +00:00
|
|
|
images1, images2 := []image.Image{}, []image.Image{}
|
pkg/images/resize: show that golang.org/x/image/draw is a win
While investigating issue #635 I remembered that golang.org/x/image/draw
might offer some interesting features. It indeed happens to have some
rescaling routines that seem to work better in the YCbCr case than our
custom code, which is illustrated by these benchmarks:
% go test -v -bench Benchmark.*YCrCb.* -run Bench* -benchmem
% ./pkg/images/resize/
PASS
BenchmarkResizeYCrCb-4 20 79213653 ns/op
9437475 B/op 5 allocs/op
BenchmarkNewResizeYCrCb-4 100 15711294 ns/op
1048668 B/op 2 allocs/op
BenchmarkHalveYCrCb-4 100 17328467 ns/op
128 B/op 1 allocs/op
ok camlistore.org/pkg/images/resize 5.889s
One can see that not only the new resize is faster, and uses less memory
than the old one, but it is also about as fast as "resizing by halving
in place". And this is with the ApproxBiLinear algorithm; some quick
additional tests seemed to indicate that NearestNeighbor was twice as
fast, with about the same memory usage. I chose ApproxBiLinear as it
seemed the most conservative choice for now.
I think it is also worth investigating whether we can be rid of "halving
in place", since it would make for simpler code overall, and since
ApproxBiLinear might be faster in most cases. It would have the nice
side-effect of solving issue #635 too. However, "halving in place" will
always win when it comes to memory usage, so it depends on our
priorities.
Finally, these other new benchmarks show that using the new resize does
not make the #635 mystery much worse (going from ~16% to ~18%), and that
interestingly the results of the old resize and the new resize are
pretty different by themselves.
% go test -v -run TestCompare ./pkg/images/resize/
=== RUN TestCompareOldResizeToHalveInplace
--- FAIL: TestCompareOldResizeToHalveInplace (2.49s)
resize_test.go:377: *image.Gray PSNR 63.7793
resize_test.go:377: *image.Gray16 PSNR 59.9547
resize_test.go:377: *image.NRGBA PSNR 62.8252
resize_test.go:377: *image.NRGBA64 PSNR 62.8252
resize_test.go:377: *image.Paletted PSNR 51.4949
resize_test.go:377: *image.RGBA PSNR 62.8252
resize_test.go:377: *image.RGBA64 PSNR 62.8252
resize_test.go:377: *image.YCbCr PSNR 61.9664
resize_test.go:382: *image.YCbCr not the same 18077 pixels
different 16.35%
resize_test.go:377: *image.YCbCr PSNR 52.4121
resize_test.go:382: *image.YCbCr not the same 18139 pixels
different 16.40%
resize_test.go:377: *image.YCbCr PSNR 51.4972
resize_test.go:382: *image.YCbCr not the same 17932 pixels
different 16.21%
resize_test.go:377: *image.YCbCr PSNR 51.6399
resize_test.go:382: *image.YCbCr not the same 17881 pixels
different 16.17%
resize_test.go:377: *image.YCbCr PSNR 50.7736
resize_test.go:382: *image.YCbCr not the same 17976 pixels
different 16.25%
resize_test.go:377: *image.YCbCr PSNR 52.4536
resize_test.go:382: *image.YCbCr not the same 18180 pixels
different 16.44%
=== RUN TestCompareNewResizeToHalveInplace
--- FAIL: TestCompareNewResizeToHalveInplace (2.27s)
resize_test.go:377: *image.Gray PSNR 63.7793
resize_test.go:377: *image.Gray16 PSNR 59.9547
resize_test.go:377: *image.NRGBA PSNR 62.8252
resize_test.go:377: *image.NRGBA64 PSNR 62.8252
resize_test.go:377: *image.Paletted PSNR 51.4949
resize_test.go:377: *image.RGBA PSNR 62.8252
resize_test.go:377: *image.RGBA64 PSNR 62.8252
resize_test.go:377: *image.YCbCr PSNR 59.5902
resize_test.go:382: *image.YCbCr not the same 20757 pixels
different 18.77%
resize_test.go:377: *image.YCbCr PSNR 52.0962
resize_test.go:382: *image.YCbCr not the same 20811 pixels
different 18.82%
resize_test.go:377: *image.YCbCr PSNR 51.3374
resize_test.go:382: *image.YCbCr not the same 20671 pixels
different 18.69%
resize_test.go:377: *image.YCbCr PSNR 51.3586
resize_test.go:382: *image.YCbCr not the same 20618 pixels
different 18.64%
resize_test.go:377: *image.YCbCr PSNR 57.2346
resize_test.go:382: *image.YCbCr not the same 20705 pixels
different 18.72%
resize_test.go:377: *image.YCbCr PSNR 50.7504
resize_test.go:382: *image.YCbCr not the same 20847 pixels
different 18.85%
=== RUN TestCompareOldResizeToNewResize
--- FAIL: TestCompareOldResizeToNewResize (2.54s)
resize_test.go:377: *image.Gray PSNR +Inf
resize_test.go:377: *image.Gray16 PSNR +Inf
resize_test.go:377: *image.NRGBA PSNR +Inf
resize_test.go:377: *image.NRGBA64 PSNR +Inf
resize_test.go:377: *image.Paletted PSNR +Inf
resize_test.go:377: *image.RGBA PSNR +Inf
resize_test.go:377: *image.RGBA64 PSNR +Inf
resize_test.go:377: *image.YCbCr PSNR 59.1024
resize_test.go:382: *image.YCbCr not the same 16350 pixels
different 14.78%
resize_test.go:377: *image.YCbCr PSNR 62.6523
resize_test.go:377: *image.YCbCr PSNR 62.7010
resize_test.go:377: *image.YCbCr PSNR 59.1396
resize_test.go:382: *image.YCbCr not the same 16225 pixels
different 14.67%
resize_test.go:377: *image.YCbCr PSNR 59.0844
resize_test.go:382: *image.YCbCr not the same 16294 pixels
different 14.73%
resize_test.go:377: *image.YCbCr PSNR 59.0534
resize_test.go:382: *image.YCbCr not the same 16413 pixels
different 14.84%
Change-Id: Ia8c578a53416ec0f1cac1477a1a68acfede84b24
2015-09-04 22:54:31 +00:00
|
|
|
var imTypes []string
|
2013-12-07 20:05:18 +00:00
|
|
|
for _, im := range makeImages(testIm.Bounds()) {
|
pkg/images/resize: show that golang.org/x/image/draw is a win
While investigating issue #635 I remembered that golang.org/x/image/draw
might offer some interesting features. It indeed happens to have some
rescaling routines that seem to work better in the YCbCr case than our
custom code, which is illustrated by these benchmarks:
% go test -v -bench Benchmark.*YCrCb.* -run Bench* -benchmem
% ./pkg/images/resize/
PASS
BenchmarkResizeYCrCb-4 20 79213653 ns/op
9437475 B/op 5 allocs/op
BenchmarkNewResizeYCrCb-4 100 15711294 ns/op
1048668 B/op 2 allocs/op
BenchmarkHalveYCrCb-4 100 17328467 ns/op
128 B/op 1 allocs/op
ok camlistore.org/pkg/images/resize 5.889s
One can see that not only the new resize is faster, and uses less memory
than the old one, but it is also about as fast as "resizing by halving
in place". And this is with the ApproxBiLinear algorithm; some quick
additional tests seemed to indicate that NearestNeighbor was twice as
fast, with about the same memory usage. I chose ApproxBiLinear as it
seemed the most conservative choice for now.
I think it is also worth investigating whether we can be rid of "halving
in place", since it would make for simpler code overall, and since
ApproxBiLinear might be faster in most cases. It would have the nice
side-effect of solving issue #635 too. However, "halving in place" will
always win when it comes to memory usage, so it depends on our
priorities.
Finally, these other new benchmarks show that using the new resize does
not make the #635 mystery much worse (going from ~16% to ~18%), and that
interestingly the results of the old resize and the new resize are
pretty different by themselves.
% go test -v -run TestCompare ./pkg/images/resize/
=== RUN TestCompareOldResizeToHalveInplace
--- FAIL: TestCompareOldResizeToHalveInplace (2.49s)
resize_test.go:377: *image.Gray PSNR 63.7793
resize_test.go:377: *image.Gray16 PSNR 59.9547
resize_test.go:377: *image.NRGBA PSNR 62.8252
resize_test.go:377: *image.NRGBA64 PSNR 62.8252
resize_test.go:377: *image.Paletted PSNR 51.4949
resize_test.go:377: *image.RGBA PSNR 62.8252
resize_test.go:377: *image.RGBA64 PSNR 62.8252
resize_test.go:377: *image.YCbCr PSNR 61.9664
resize_test.go:382: *image.YCbCr not the same 18077 pixels
different 16.35%
resize_test.go:377: *image.YCbCr PSNR 52.4121
resize_test.go:382: *image.YCbCr not the same 18139 pixels
different 16.40%
resize_test.go:377: *image.YCbCr PSNR 51.4972
resize_test.go:382: *image.YCbCr not the same 17932 pixels
different 16.21%
resize_test.go:377: *image.YCbCr PSNR 51.6399
resize_test.go:382: *image.YCbCr not the same 17881 pixels
different 16.17%
resize_test.go:377: *image.YCbCr PSNR 50.7736
resize_test.go:382: *image.YCbCr not the same 17976 pixels
different 16.25%
resize_test.go:377: *image.YCbCr PSNR 52.4536
resize_test.go:382: *image.YCbCr not the same 18180 pixels
different 16.44%
=== RUN TestCompareNewResizeToHalveInplace
--- FAIL: TestCompareNewResizeToHalveInplace (2.27s)
resize_test.go:377: *image.Gray PSNR 63.7793
resize_test.go:377: *image.Gray16 PSNR 59.9547
resize_test.go:377: *image.NRGBA PSNR 62.8252
resize_test.go:377: *image.NRGBA64 PSNR 62.8252
resize_test.go:377: *image.Paletted PSNR 51.4949
resize_test.go:377: *image.RGBA PSNR 62.8252
resize_test.go:377: *image.RGBA64 PSNR 62.8252
resize_test.go:377: *image.YCbCr PSNR 59.5902
resize_test.go:382: *image.YCbCr not the same 20757 pixels
different 18.77%
resize_test.go:377: *image.YCbCr PSNR 52.0962
resize_test.go:382: *image.YCbCr not the same 20811 pixels
different 18.82%
resize_test.go:377: *image.YCbCr PSNR 51.3374
resize_test.go:382: *image.YCbCr not the same 20671 pixels
different 18.69%
resize_test.go:377: *image.YCbCr PSNR 51.3586
resize_test.go:382: *image.YCbCr not the same 20618 pixels
different 18.64%
resize_test.go:377: *image.YCbCr PSNR 57.2346
resize_test.go:382: *image.YCbCr not the same 20705 pixels
different 18.72%
resize_test.go:377: *image.YCbCr PSNR 50.7504
resize_test.go:382: *image.YCbCr not the same 20847 pixels
different 18.85%
=== RUN TestCompareOldResizeToNewResize
--- FAIL: TestCompareOldResizeToNewResize (2.54s)
resize_test.go:377: *image.Gray PSNR +Inf
resize_test.go:377: *image.Gray16 PSNR +Inf
resize_test.go:377: *image.NRGBA PSNR +Inf
resize_test.go:377: *image.NRGBA64 PSNR +Inf
resize_test.go:377: *image.Paletted PSNR +Inf
resize_test.go:377: *image.RGBA PSNR +Inf
resize_test.go:377: *image.RGBA64 PSNR +Inf
resize_test.go:377: *image.YCbCr PSNR 59.1024
resize_test.go:382: *image.YCbCr not the same 16350 pixels
different 14.78%
resize_test.go:377: *image.YCbCr PSNR 62.6523
resize_test.go:377: *image.YCbCr PSNR 62.7010
resize_test.go:377: *image.YCbCr PSNR 59.1396
resize_test.go:382: *image.YCbCr not the same 16225 pixels
different 14.67%
resize_test.go:377: *image.YCbCr PSNR 59.0844
resize_test.go:382: *image.YCbCr not the same 16294 pixels
different 14.73%
resize_test.go:377: *image.YCbCr PSNR 59.0534
resize_test.go:382: *image.YCbCr not the same 16413 pixels
different 14.84%
Change-Id: Ia8c578a53416ec0f1cac1477a1a68acfede84b24
2015-09-04 22:54:31 +00:00
|
|
|
// keeping track of the types for the final output
|
2015-11-20 20:40:22 +00:00
|
|
|
imgType := fmt.Sprintf("%T", im)
|
|
|
|
imgType = imgType[strings.Index(imgType, ".")+1:]
|
|
|
|
if m, ok := im.(*image.YCbCr); ok {
|
|
|
|
imgType += "." + m.SubsampleRatio.String()
|
|
|
|
}
|
|
|
|
imTypes = append(imTypes, imgType)
|
2013-12-07 20:05:18 +00:00
|
|
|
fillTestImage(im)
|
pkg/images/resize: show that golang.org/x/image/draw is a win
While investigating issue #635 I remembered that golang.org/x/image/draw
might offer some interesting features. It indeed happens to have some
rescaling routines that seem to work better in the YCbCr case than our
custom code, which is illustrated by these benchmarks:
% go test -v -bench Benchmark.*YCrCb.* -run Bench* -benchmem
% ./pkg/images/resize/
PASS
BenchmarkResizeYCrCb-4 20 79213653 ns/op
9437475 B/op 5 allocs/op
BenchmarkNewResizeYCrCb-4 100 15711294 ns/op
1048668 B/op 2 allocs/op
BenchmarkHalveYCrCb-4 100 17328467 ns/op
128 B/op 1 allocs/op
ok camlistore.org/pkg/images/resize 5.889s
One can see that not only the new resize is faster, and uses less memory
than the old one, but it is also about as fast as "resizing by halving
in place". And this is with the ApproxBiLinear algorithm; some quick
additional tests seemed to indicate that NearestNeighbor was twice as
fast, with about the same memory usage. I chose ApproxBiLinear as it
seemed the most conservative choice for now.
I think it is also worth investigating whether we can be rid of "halving
in place", since it would make for simpler code overall, and since
ApproxBiLinear might be faster in most cases. It would have the nice
side-effect of solving issue #635 too. However, "halving in place" will
always win when it comes to memory usage, so it depends on our
priorities.
Finally, these other new benchmarks show that using the new resize does
not make the #635 mystery much worse (going from ~16% to ~18%), and that
interestingly the results of the old resize and the new resize are
pretty different by themselves.
% go test -v -run TestCompare ./pkg/images/resize/
=== RUN TestCompareOldResizeToHalveInplace
--- FAIL: TestCompareOldResizeToHalveInplace (2.49s)
resize_test.go:377: *image.Gray PSNR 63.7793
resize_test.go:377: *image.Gray16 PSNR 59.9547
resize_test.go:377: *image.NRGBA PSNR 62.8252
resize_test.go:377: *image.NRGBA64 PSNR 62.8252
resize_test.go:377: *image.Paletted PSNR 51.4949
resize_test.go:377: *image.RGBA PSNR 62.8252
resize_test.go:377: *image.RGBA64 PSNR 62.8252
resize_test.go:377: *image.YCbCr PSNR 61.9664
resize_test.go:382: *image.YCbCr not the same 18077 pixels
different 16.35%
resize_test.go:377: *image.YCbCr PSNR 52.4121
resize_test.go:382: *image.YCbCr not the same 18139 pixels
different 16.40%
resize_test.go:377: *image.YCbCr PSNR 51.4972
resize_test.go:382: *image.YCbCr not the same 17932 pixels
different 16.21%
resize_test.go:377: *image.YCbCr PSNR 51.6399
resize_test.go:382: *image.YCbCr not the same 17881 pixels
different 16.17%
resize_test.go:377: *image.YCbCr PSNR 50.7736
resize_test.go:382: *image.YCbCr not the same 17976 pixels
different 16.25%
resize_test.go:377: *image.YCbCr PSNR 52.4536
resize_test.go:382: *image.YCbCr not the same 18180 pixels
different 16.44%
=== RUN TestCompareNewResizeToHalveInplace
--- FAIL: TestCompareNewResizeToHalveInplace (2.27s)
resize_test.go:377: *image.Gray PSNR 63.7793
resize_test.go:377: *image.Gray16 PSNR 59.9547
resize_test.go:377: *image.NRGBA PSNR 62.8252
resize_test.go:377: *image.NRGBA64 PSNR 62.8252
resize_test.go:377: *image.Paletted PSNR 51.4949
resize_test.go:377: *image.RGBA PSNR 62.8252
resize_test.go:377: *image.RGBA64 PSNR 62.8252
resize_test.go:377: *image.YCbCr PSNR 59.5902
resize_test.go:382: *image.YCbCr not the same 20757 pixels
different 18.77%
resize_test.go:377: *image.YCbCr PSNR 52.0962
resize_test.go:382: *image.YCbCr not the same 20811 pixels
different 18.82%
resize_test.go:377: *image.YCbCr PSNR 51.3374
resize_test.go:382: *image.YCbCr not the same 20671 pixels
different 18.69%
resize_test.go:377: *image.YCbCr PSNR 51.3586
resize_test.go:382: *image.YCbCr not the same 20618 pixels
different 18.64%
resize_test.go:377: *image.YCbCr PSNR 57.2346
resize_test.go:382: *image.YCbCr not the same 20705 pixels
different 18.72%
resize_test.go:377: *image.YCbCr PSNR 50.7504
resize_test.go:382: *image.YCbCr not the same 20847 pixels
different 18.85%
=== RUN TestCompareOldResizeToNewResize
--- FAIL: TestCompareOldResizeToNewResize (2.54s)
resize_test.go:377: *image.Gray PSNR +Inf
resize_test.go:377: *image.Gray16 PSNR +Inf
resize_test.go:377: *image.NRGBA PSNR +Inf
resize_test.go:377: *image.NRGBA64 PSNR +Inf
resize_test.go:377: *image.Paletted PSNR +Inf
resize_test.go:377: *image.RGBA PSNR +Inf
resize_test.go:377: *image.RGBA64 PSNR +Inf
resize_test.go:377: *image.YCbCr PSNR 59.1024
resize_test.go:382: *image.YCbCr not the same 16350 pixels
different 14.78%
resize_test.go:377: *image.YCbCr PSNR 62.6523
resize_test.go:377: *image.YCbCr PSNR 62.7010
resize_test.go:377: *image.YCbCr PSNR 59.1396
resize_test.go:382: *image.YCbCr not the same 16225 pixels
different 14.67%
resize_test.go:377: *image.YCbCr PSNR 59.0844
resize_test.go:382: *image.YCbCr not the same 16294 pixels
different 14.73%
resize_test.go:377: *image.YCbCr PSNR 59.0534
resize_test.go:382: *image.YCbCr not the same 16413 pixels
different 14.84%
Change-Id: Ia8c578a53416ec0f1cac1477a1a68acfede84b24
2015-09-04 22:54:31 +00:00
|
|
|
images1 = append(images1, resizeMethods[method1](im))
|
2013-12-07 20:05:18 +00:00
|
|
|
}
|
|
|
|
for _, im := range makeImages(testIm.Bounds()) {
|
|
|
|
fillTestImage(im)
|
pkg/images/resize: show that golang.org/x/image/draw is a win
While investigating issue #635 I remembered that golang.org/x/image/draw
might offer some interesting features. It indeed happens to have some
rescaling routines that seem to work better in the YCbCr case than our
custom code, which is illustrated by these benchmarks:
% go test -v -bench Benchmark.*YCrCb.* -run Bench* -benchmem
% ./pkg/images/resize/
PASS
BenchmarkResizeYCrCb-4 20 79213653 ns/op
9437475 B/op 5 allocs/op
BenchmarkNewResizeYCrCb-4 100 15711294 ns/op
1048668 B/op 2 allocs/op
BenchmarkHalveYCrCb-4 100 17328467 ns/op
128 B/op 1 allocs/op
ok camlistore.org/pkg/images/resize 5.889s
One can see that not only the new resize is faster, and uses less memory
than the old one, but it is also about as fast as "resizing by halving
in place". And this is with the ApproxBiLinear algorithm; some quick
additional tests seemed to indicate that NearestNeighbor was twice as
fast, with about the same memory usage. I chose ApproxBiLinear as it
seemed the most conservative choice for now.
I think it is also worth investigating whether we can be rid of "halving
in place", since it would make for simpler code overall, and since
ApproxBiLinear might be faster in most cases. It would have the nice
side-effect of solving issue #635 too. However, "halving in place" will
always win when it comes to memory usage, so it depends on our
priorities.
Finally, these other new benchmarks show that using the new resize does
not make the #635 mystery much worse (going from ~16% to ~18%), and that
interestingly the results of the old resize and the new resize are
pretty different by themselves.
% go test -v -run TestCompare ./pkg/images/resize/
=== RUN TestCompareOldResizeToHalveInplace
--- FAIL: TestCompareOldResizeToHalveInplace (2.49s)
resize_test.go:377: *image.Gray PSNR 63.7793
resize_test.go:377: *image.Gray16 PSNR 59.9547
resize_test.go:377: *image.NRGBA PSNR 62.8252
resize_test.go:377: *image.NRGBA64 PSNR 62.8252
resize_test.go:377: *image.Paletted PSNR 51.4949
resize_test.go:377: *image.RGBA PSNR 62.8252
resize_test.go:377: *image.RGBA64 PSNR 62.8252
resize_test.go:377: *image.YCbCr PSNR 61.9664
resize_test.go:382: *image.YCbCr not the same 18077 pixels
different 16.35%
resize_test.go:377: *image.YCbCr PSNR 52.4121
resize_test.go:382: *image.YCbCr not the same 18139 pixels
different 16.40%
resize_test.go:377: *image.YCbCr PSNR 51.4972
resize_test.go:382: *image.YCbCr not the same 17932 pixels
different 16.21%
resize_test.go:377: *image.YCbCr PSNR 51.6399
resize_test.go:382: *image.YCbCr not the same 17881 pixels
different 16.17%
resize_test.go:377: *image.YCbCr PSNR 50.7736
resize_test.go:382: *image.YCbCr not the same 17976 pixels
different 16.25%
resize_test.go:377: *image.YCbCr PSNR 52.4536
resize_test.go:382: *image.YCbCr not the same 18180 pixels
different 16.44%
=== RUN TestCompareNewResizeToHalveInplace
--- FAIL: TestCompareNewResizeToHalveInplace (2.27s)
resize_test.go:377: *image.Gray PSNR 63.7793
resize_test.go:377: *image.Gray16 PSNR 59.9547
resize_test.go:377: *image.NRGBA PSNR 62.8252
resize_test.go:377: *image.NRGBA64 PSNR 62.8252
resize_test.go:377: *image.Paletted PSNR 51.4949
resize_test.go:377: *image.RGBA PSNR 62.8252
resize_test.go:377: *image.RGBA64 PSNR 62.8252
resize_test.go:377: *image.YCbCr PSNR 59.5902
resize_test.go:382: *image.YCbCr not the same 20757 pixels
different 18.77%
resize_test.go:377: *image.YCbCr PSNR 52.0962
resize_test.go:382: *image.YCbCr not the same 20811 pixels
different 18.82%
resize_test.go:377: *image.YCbCr PSNR 51.3374
resize_test.go:382: *image.YCbCr not the same 20671 pixels
different 18.69%
resize_test.go:377: *image.YCbCr PSNR 51.3586
resize_test.go:382: *image.YCbCr not the same 20618 pixels
different 18.64%
resize_test.go:377: *image.YCbCr PSNR 57.2346
resize_test.go:382: *image.YCbCr not the same 20705 pixels
different 18.72%
resize_test.go:377: *image.YCbCr PSNR 50.7504
resize_test.go:382: *image.YCbCr not the same 20847 pixels
different 18.85%
=== RUN TestCompareOldResizeToNewResize
--- FAIL: TestCompareOldResizeToNewResize (2.54s)
resize_test.go:377: *image.Gray PSNR +Inf
resize_test.go:377: *image.Gray16 PSNR +Inf
resize_test.go:377: *image.NRGBA PSNR +Inf
resize_test.go:377: *image.NRGBA64 PSNR +Inf
resize_test.go:377: *image.Paletted PSNR +Inf
resize_test.go:377: *image.RGBA PSNR +Inf
resize_test.go:377: *image.RGBA64 PSNR +Inf
resize_test.go:377: *image.YCbCr PSNR 59.1024
resize_test.go:382: *image.YCbCr not the same 16350 pixels
different 14.78%
resize_test.go:377: *image.YCbCr PSNR 62.6523
resize_test.go:377: *image.YCbCr PSNR 62.7010
resize_test.go:377: *image.YCbCr PSNR 59.1396
resize_test.go:382: *image.YCbCr not the same 16225 pixels
different 14.67%
resize_test.go:377: *image.YCbCr PSNR 59.0844
resize_test.go:382: *image.YCbCr not the same 16294 pixels
different 14.73%
resize_test.go:377: *image.YCbCr PSNR 59.0534
resize_test.go:382: *image.YCbCr not the same 16413 pixels
different 14.84%
Change-Id: Ia8c578a53416ec0f1cac1477a1a68acfede84b24
2015-09-04 22:54:31 +00:00
|
|
|
images2 = append(images2, resizeMethods[method2](im))
|
2013-12-07 20:05:18 +00:00
|
|
|
}
|
|
|
|
var (
|
|
|
|
f io.WriteCloser
|
|
|
|
err error
|
|
|
|
)
|
2015-11-23 22:16:18 +00:00
|
|
|
if *flagOutput != "" {
|
|
|
|
os.Mkdir(*flagOutput, os.FileMode(0777))
|
|
|
|
f, err = os.Create(filepath.Join(*flagOutput, "index.html"))
|
2013-12-07 20:05:18 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
defer f.Close()
|
|
|
|
fmt.Fprintf(f, `<!DOCTYPE html>
|
|
|
|
<html lang="en">
|
|
|
|
<head>
|
|
|
|
<meta charset="utf-8">
|
pkg/images/resize: show that golang.org/x/image/draw is a win
While investigating issue #635 I remembered that golang.org/x/image/draw
might offer some interesting features. It indeed happens to have some
rescaling routines that seem to work better in the YCbCr case than our
custom code, which is illustrated by these benchmarks:
% go test -v -bench Benchmark.*YCrCb.* -run Bench* -benchmem
% ./pkg/images/resize/
PASS
BenchmarkResizeYCrCb-4 20 79213653 ns/op
9437475 B/op 5 allocs/op
BenchmarkNewResizeYCrCb-4 100 15711294 ns/op
1048668 B/op 2 allocs/op
BenchmarkHalveYCrCb-4 100 17328467 ns/op
128 B/op 1 allocs/op
ok camlistore.org/pkg/images/resize 5.889s
One can see that not only the new resize is faster, and uses less memory
than the old one, but it is also about as fast as "resizing by halving
in place". And this is with the ApproxBiLinear algorithm; some quick
additional tests seemed to indicate that NearestNeighbor was twice as
fast, with about the same memory usage. I chose ApproxBiLinear as it
seemed the most conservative choice for now.
I think it is also worth investigating whether we can be rid of "halving
in place", since it would make for simpler code overall, and since
ApproxBiLinear might be faster in most cases. It would have the nice
side-effect of solving issue #635 too. However, "halving in place" will
always win when it comes to memory usage, so it depends on our
priorities.
Finally, these other new benchmarks show that using the new resize does
not make the #635 mystery much worse (going from ~16% to ~18%), and that
interestingly the results of the old resize and the new resize are
pretty different by themselves.
% go test -v -run TestCompare ./pkg/images/resize/
=== RUN TestCompareOldResizeToHalveInplace
--- FAIL: TestCompareOldResizeToHalveInplace (2.49s)
resize_test.go:377: *image.Gray PSNR 63.7793
resize_test.go:377: *image.Gray16 PSNR 59.9547
resize_test.go:377: *image.NRGBA PSNR 62.8252
resize_test.go:377: *image.NRGBA64 PSNR 62.8252
resize_test.go:377: *image.Paletted PSNR 51.4949
resize_test.go:377: *image.RGBA PSNR 62.8252
resize_test.go:377: *image.RGBA64 PSNR 62.8252
resize_test.go:377: *image.YCbCr PSNR 61.9664
resize_test.go:382: *image.YCbCr not the same 18077 pixels
different 16.35%
resize_test.go:377: *image.YCbCr PSNR 52.4121
resize_test.go:382: *image.YCbCr not the same 18139 pixels
different 16.40%
resize_test.go:377: *image.YCbCr PSNR 51.4972
resize_test.go:382: *image.YCbCr not the same 17932 pixels
different 16.21%
resize_test.go:377: *image.YCbCr PSNR 51.6399
resize_test.go:382: *image.YCbCr not the same 17881 pixels
different 16.17%
resize_test.go:377: *image.YCbCr PSNR 50.7736
resize_test.go:382: *image.YCbCr not the same 17976 pixels
different 16.25%
resize_test.go:377: *image.YCbCr PSNR 52.4536
resize_test.go:382: *image.YCbCr not the same 18180 pixels
different 16.44%
=== RUN TestCompareNewResizeToHalveInplace
--- FAIL: TestCompareNewResizeToHalveInplace (2.27s)
resize_test.go:377: *image.Gray PSNR 63.7793
resize_test.go:377: *image.Gray16 PSNR 59.9547
resize_test.go:377: *image.NRGBA PSNR 62.8252
resize_test.go:377: *image.NRGBA64 PSNR 62.8252
resize_test.go:377: *image.Paletted PSNR 51.4949
resize_test.go:377: *image.RGBA PSNR 62.8252
resize_test.go:377: *image.RGBA64 PSNR 62.8252
resize_test.go:377: *image.YCbCr PSNR 59.5902
resize_test.go:382: *image.YCbCr not the same 20757 pixels
different 18.77%
resize_test.go:377: *image.YCbCr PSNR 52.0962
resize_test.go:382: *image.YCbCr not the same 20811 pixels
different 18.82%
resize_test.go:377: *image.YCbCr PSNR 51.3374
resize_test.go:382: *image.YCbCr not the same 20671 pixels
different 18.69%
resize_test.go:377: *image.YCbCr PSNR 51.3586
resize_test.go:382: *image.YCbCr not the same 20618 pixels
different 18.64%
resize_test.go:377: *image.YCbCr PSNR 57.2346
resize_test.go:382: *image.YCbCr not the same 20705 pixels
different 18.72%
resize_test.go:377: *image.YCbCr PSNR 50.7504
resize_test.go:382: *image.YCbCr not the same 20847 pixels
different 18.85%
=== RUN TestCompareOldResizeToNewResize
--- FAIL: TestCompareOldResizeToNewResize (2.54s)
resize_test.go:377: *image.Gray PSNR +Inf
resize_test.go:377: *image.Gray16 PSNR +Inf
resize_test.go:377: *image.NRGBA PSNR +Inf
resize_test.go:377: *image.NRGBA64 PSNR +Inf
resize_test.go:377: *image.Paletted PSNR +Inf
resize_test.go:377: *image.RGBA PSNR +Inf
resize_test.go:377: *image.RGBA64 PSNR +Inf
resize_test.go:377: *image.YCbCr PSNR 59.1024
resize_test.go:382: *image.YCbCr not the same 16350 pixels
different 14.78%
resize_test.go:377: *image.YCbCr PSNR 62.6523
resize_test.go:377: *image.YCbCr PSNR 62.7010
resize_test.go:377: *image.YCbCr PSNR 59.1396
resize_test.go:382: *image.YCbCr not the same 16225 pixels
different 14.67%
resize_test.go:377: *image.YCbCr PSNR 59.0844
resize_test.go:382: *image.YCbCr not the same 16294 pixels
different 14.73%
resize_test.go:377: *image.YCbCr PSNR 59.0534
resize_test.go:382: *image.YCbCr not the same 16413 pixels
different 14.84%
Change-Id: Ia8c578a53416ec0f1cac1477a1a68acfede84b24
2015-09-04 22:54:31 +00:00
|
|
|
<title>Image comparison for `+method1+` vs `+method2+`</title>
|
2013-12-07 20:05:18 +00:00
|
|
|
</head>
|
|
|
|
<body style="background-color: grey">
|
|
|
|
<table>
|
|
|
|
`)
|
|
|
|
}
|
|
|
|
for i, im1 := range images1 {
|
|
|
|
im2 := images2[i]
|
2015-11-23 22:16:18 +00:00
|
|
|
res := compareImages(im1, im2, false)
|
|
|
|
if *flagOutput != "" {
|
2013-12-07 20:05:18 +00:00
|
|
|
fmt.Fprintf(f, "<tr>")
|
2015-11-23 22:16:18 +00:00
|
|
|
fn := getFilename(imTypes[i], method1)
|
|
|
|
halved := fn
|
2013-12-07 20:05:18 +00:00
|
|
|
err := savePng(t, im1, fn)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
fmt.Fprintf(f, `<td><img src="%s"><br>%s`, fn, fn)
|
|
|
|
|
2015-11-23 22:16:18 +00:00
|
|
|
fn = getFilename(imTypes[i], method2)
|
|
|
|
resized := fn
|
2013-12-07 20:05:18 +00:00
|
|
|
err = savePng(t, im2, fn)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
fmt.Fprintf(f, `<td><img src="%s"><br>%s`, fn, fn)
|
|
|
|
|
|
|
|
if res.diffIm != nil {
|
2015-11-20 20:40:22 +00:00
|
|
|
fn = getFilename(imTypes[i], "diff")
|
2013-12-07 20:05:18 +00:00
|
|
|
err = savePng(t, res.diffIm, fn)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
fmt.Fprintf(f, `<td><img src="%s"><br>%s`, fn, fn)
|
2015-11-23 22:16:18 +00:00
|
|
|
if *flagUseIM {
|
|
|
|
cmd := exec.Command("compare", "-verbose", "-metric", "psnr",
|
|
|
|
filepath.Join(*flagOutput, halved), filepath.Join(*flagOutput, resized), filepath.Join(*flagOutput, "imagemagick-"+fn))
|
|
|
|
if output, err := cmd.CombinedOutput(); err != nil {
|
Rename import paths from camlistore.org to perkeep.org.
Part of the project renaming, issue #981.
After this, users will need to mv their $GOPATH/src/camlistore.org to
$GOPATH/src/perkeep.org. Sorry.
This doesn't yet rename the tools like camlistored, camput, camget,
camtool, etc.
Also, this only moves the lru package to internal. More will move to
internal later.
Also, this doesn't yet remove the "/pkg/" directory. That'll likely
happen later.
This updates some docs, but not all.
devcam test now passes again, even with Go 1.10 (which requires vet
checks are clean too). So a bunch of vet tests are fixed in this CL
too, and a bunch of other broken tests are now fixed (introduced from
the past week of merging the CL backlog).
Change-Id: If580db1691b5b99f8ed6195070789b1f44877dd4
2018-01-01 22:41:41 +00:00
|
|
|
t.Fatalf("%v: %v", string(output), err)
|
2015-11-23 22:16:18 +00:00
|
|
|
} else {
|
|
|
|
t.Logf("%v", string(output))
|
|
|
|
}
|
|
|
|
}
|
2013-12-07 20:05:18 +00:00
|
|
|
}
|
|
|
|
fmt.Fprintln(f)
|
|
|
|
}
|
|
|
|
|
|
|
|
if res.psnr < psnrThreshold {
|
pkg/images/resize: show that golang.org/x/image/draw is a win
While investigating issue #635 I remembered that golang.org/x/image/draw
might offer some interesting features. It indeed happens to have some
rescaling routines that seem to work better in the YCbCr case than our
custom code, which is illustrated by these benchmarks:
% go test -v -bench Benchmark.*YCrCb.* -run Bench* -benchmem
% ./pkg/images/resize/
PASS
BenchmarkResizeYCrCb-4 20 79213653 ns/op
9437475 B/op 5 allocs/op
BenchmarkNewResizeYCrCb-4 100 15711294 ns/op
1048668 B/op 2 allocs/op
BenchmarkHalveYCrCb-4 100 17328467 ns/op
128 B/op 1 allocs/op
ok camlistore.org/pkg/images/resize 5.889s
One can see that not only the new resize is faster, and uses less memory
than the old one, but it is also about as fast as "resizing by halving
in place". And this is with the ApproxBiLinear algorithm; some quick
additional tests seemed to indicate that NearestNeighbor was twice as
fast, with about the same memory usage. I chose ApproxBiLinear as it
seemed the most conservative choice for now.
I think it is also worth investigating whether we can be rid of "halving
in place", since it would make for simpler code overall, and since
ApproxBiLinear might be faster in most cases. It would have the nice
side-effect of solving issue #635 too. However, "halving in place" will
always win when it comes to memory usage, so it depends on our
priorities.
Finally, these other new benchmarks show that using the new resize does
not make the #635 mystery much worse (going from ~16% to ~18%), and that
interestingly the results of the old resize and the new resize are
pretty different by themselves.
% go test -v -run TestCompare ./pkg/images/resize/
=== RUN TestCompareOldResizeToHalveInplace
--- FAIL: TestCompareOldResizeToHalveInplace (2.49s)
resize_test.go:377: *image.Gray PSNR 63.7793
resize_test.go:377: *image.Gray16 PSNR 59.9547
resize_test.go:377: *image.NRGBA PSNR 62.8252
resize_test.go:377: *image.NRGBA64 PSNR 62.8252
resize_test.go:377: *image.Paletted PSNR 51.4949
resize_test.go:377: *image.RGBA PSNR 62.8252
resize_test.go:377: *image.RGBA64 PSNR 62.8252
resize_test.go:377: *image.YCbCr PSNR 61.9664
resize_test.go:382: *image.YCbCr not the same 18077 pixels
different 16.35%
resize_test.go:377: *image.YCbCr PSNR 52.4121
resize_test.go:382: *image.YCbCr not the same 18139 pixels
different 16.40%
resize_test.go:377: *image.YCbCr PSNR 51.4972
resize_test.go:382: *image.YCbCr not the same 17932 pixels
different 16.21%
resize_test.go:377: *image.YCbCr PSNR 51.6399
resize_test.go:382: *image.YCbCr not the same 17881 pixels
different 16.17%
resize_test.go:377: *image.YCbCr PSNR 50.7736
resize_test.go:382: *image.YCbCr not the same 17976 pixels
different 16.25%
resize_test.go:377: *image.YCbCr PSNR 52.4536
resize_test.go:382: *image.YCbCr not the same 18180 pixels
different 16.44%
=== RUN TestCompareNewResizeToHalveInplace
--- FAIL: TestCompareNewResizeToHalveInplace (2.27s)
resize_test.go:377: *image.Gray PSNR 63.7793
resize_test.go:377: *image.Gray16 PSNR 59.9547
resize_test.go:377: *image.NRGBA PSNR 62.8252
resize_test.go:377: *image.NRGBA64 PSNR 62.8252
resize_test.go:377: *image.Paletted PSNR 51.4949
resize_test.go:377: *image.RGBA PSNR 62.8252
resize_test.go:377: *image.RGBA64 PSNR 62.8252
resize_test.go:377: *image.YCbCr PSNR 59.5902
resize_test.go:382: *image.YCbCr not the same 20757 pixels
different 18.77%
resize_test.go:377: *image.YCbCr PSNR 52.0962
resize_test.go:382: *image.YCbCr not the same 20811 pixels
different 18.82%
resize_test.go:377: *image.YCbCr PSNR 51.3374
resize_test.go:382: *image.YCbCr not the same 20671 pixels
different 18.69%
resize_test.go:377: *image.YCbCr PSNR 51.3586
resize_test.go:382: *image.YCbCr not the same 20618 pixels
different 18.64%
resize_test.go:377: *image.YCbCr PSNR 57.2346
resize_test.go:382: *image.YCbCr not the same 20705 pixels
different 18.72%
resize_test.go:377: *image.YCbCr PSNR 50.7504
resize_test.go:382: *image.YCbCr not the same 20847 pixels
different 18.85%
=== RUN TestCompareOldResizeToNewResize
--- FAIL: TestCompareOldResizeToNewResize (2.54s)
resize_test.go:377: *image.Gray PSNR +Inf
resize_test.go:377: *image.Gray16 PSNR +Inf
resize_test.go:377: *image.NRGBA PSNR +Inf
resize_test.go:377: *image.NRGBA64 PSNR +Inf
resize_test.go:377: *image.Paletted PSNR +Inf
resize_test.go:377: *image.RGBA PSNR +Inf
resize_test.go:377: *image.RGBA64 PSNR +Inf
resize_test.go:377: *image.YCbCr PSNR 59.1024
resize_test.go:382: *image.YCbCr not the same 16350 pixels
different 14.78%
resize_test.go:377: *image.YCbCr PSNR 62.6523
resize_test.go:377: *image.YCbCr PSNR 62.7010
resize_test.go:377: *image.YCbCr PSNR 59.1396
resize_test.go:382: *image.YCbCr not the same 16225 pixels
different 14.67%
resize_test.go:377: *image.YCbCr PSNR 59.0844
resize_test.go:382: *image.YCbCr not the same 16294 pixels
different 14.73%
resize_test.go:377: *image.YCbCr PSNR 59.0534
resize_test.go:382: *image.YCbCr not the same 16413 pixels
different 14.84%
Change-Id: Ia8c578a53416ec0f1cac1477a1a68acfede84b24
2015-09-04 22:54:31 +00:00
|
|
|
t.Errorf("%v PSNR too low %.4f", imTypes[i], res.psnr)
|
2013-12-07 20:05:18 +00:00
|
|
|
} else {
|
pkg/images/resize: show that golang.org/x/image/draw is a win
While investigating issue #635 I remembered that golang.org/x/image/draw
might offer some interesting features. It indeed happens to have some
rescaling routines that seem to work better in the YCbCr case than our
custom code, which is illustrated by these benchmarks:
% go test -v -bench Benchmark.*YCrCb.* -run Bench* -benchmem
% ./pkg/images/resize/
PASS
BenchmarkResizeYCrCb-4 20 79213653 ns/op
9437475 B/op 5 allocs/op
BenchmarkNewResizeYCrCb-4 100 15711294 ns/op
1048668 B/op 2 allocs/op
BenchmarkHalveYCrCb-4 100 17328467 ns/op
128 B/op 1 allocs/op
ok camlistore.org/pkg/images/resize 5.889s
One can see that not only the new resize is faster, and uses less memory
than the old one, but it is also about as fast as "resizing by halving
in place". And this is with the ApproxBiLinear algorithm; some quick
additional tests seemed to indicate that NearestNeighbor was twice as
fast, with about the same memory usage. I chose ApproxBiLinear as it
seemed the most conservative choice for now.
I think it is also worth investigating whether we can be rid of "halving
in place", since it would make for simpler code overall, and since
ApproxBiLinear might be faster in most cases. It would have the nice
side-effect of solving issue #635 too. However, "halving in place" will
always win when it comes to memory usage, so it depends on our
priorities.
Finally, these other new benchmarks show that using the new resize does
not make the #635 mystery much worse (going from ~16% to ~18%), and that
interestingly the results of the old resize and the new resize are
pretty different by themselves.
% go test -v -run TestCompare ./pkg/images/resize/
=== RUN TestCompareOldResizeToHalveInplace
--- FAIL: TestCompareOldResizeToHalveInplace (2.49s)
resize_test.go:377: *image.Gray PSNR 63.7793
resize_test.go:377: *image.Gray16 PSNR 59.9547
resize_test.go:377: *image.NRGBA PSNR 62.8252
resize_test.go:377: *image.NRGBA64 PSNR 62.8252
resize_test.go:377: *image.Paletted PSNR 51.4949
resize_test.go:377: *image.RGBA PSNR 62.8252
resize_test.go:377: *image.RGBA64 PSNR 62.8252
resize_test.go:377: *image.YCbCr PSNR 61.9664
resize_test.go:382: *image.YCbCr not the same 18077 pixels
different 16.35%
resize_test.go:377: *image.YCbCr PSNR 52.4121
resize_test.go:382: *image.YCbCr not the same 18139 pixels
different 16.40%
resize_test.go:377: *image.YCbCr PSNR 51.4972
resize_test.go:382: *image.YCbCr not the same 17932 pixels
different 16.21%
resize_test.go:377: *image.YCbCr PSNR 51.6399
resize_test.go:382: *image.YCbCr not the same 17881 pixels
different 16.17%
resize_test.go:377: *image.YCbCr PSNR 50.7736
resize_test.go:382: *image.YCbCr not the same 17976 pixels
different 16.25%
resize_test.go:377: *image.YCbCr PSNR 52.4536
resize_test.go:382: *image.YCbCr not the same 18180 pixels
different 16.44%
=== RUN TestCompareNewResizeToHalveInplace
--- FAIL: TestCompareNewResizeToHalveInplace (2.27s)
resize_test.go:377: *image.Gray PSNR 63.7793
resize_test.go:377: *image.Gray16 PSNR 59.9547
resize_test.go:377: *image.NRGBA PSNR 62.8252
resize_test.go:377: *image.NRGBA64 PSNR 62.8252
resize_test.go:377: *image.Paletted PSNR 51.4949
resize_test.go:377: *image.RGBA PSNR 62.8252
resize_test.go:377: *image.RGBA64 PSNR 62.8252
resize_test.go:377: *image.YCbCr PSNR 59.5902
resize_test.go:382: *image.YCbCr not the same 20757 pixels
different 18.77%
resize_test.go:377: *image.YCbCr PSNR 52.0962
resize_test.go:382: *image.YCbCr not the same 20811 pixels
different 18.82%
resize_test.go:377: *image.YCbCr PSNR 51.3374
resize_test.go:382: *image.YCbCr not the same 20671 pixels
different 18.69%
resize_test.go:377: *image.YCbCr PSNR 51.3586
resize_test.go:382: *image.YCbCr not the same 20618 pixels
different 18.64%
resize_test.go:377: *image.YCbCr PSNR 57.2346
resize_test.go:382: *image.YCbCr not the same 20705 pixels
different 18.72%
resize_test.go:377: *image.YCbCr PSNR 50.7504
resize_test.go:382: *image.YCbCr not the same 20847 pixels
different 18.85%
=== RUN TestCompareOldResizeToNewResize
--- FAIL: TestCompareOldResizeToNewResize (2.54s)
resize_test.go:377: *image.Gray PSNR +Inf
resize_test.go:377: *image.Gray16 PSNR +Inf
resize_test.go:377: *image.NRGBA PSNR +Inf
resize_test.go:377: *image.NRGBA64 PSNR +Inf
resize_test.go:377: *image.Paletted PSNR +Inf
resize_test.go:377: *image.RGBA PSNR +Inf
resize_test.go:377: *image.RGBA64 PSNR +Inf
resize_test.go:377: *image.YCbCr PSNR 59.1024
resize_test.go:382: *image.YCbCr not the same 16350 pixels
different 14.78%
resize_test.go:377: *image.YCbCr PSNR 62.6523
resize_test.go:377: *image.YCbCr PSNR 62.7010
resize_test.go:377: *image.YCbCr PSNR 59.1396
resize_test.go:382: *image.YCbCr not the same 16225 pixels
different 14.67%
resize_test.go:377: *image.YCbCr PSNR 59.0844
resize_test.go:382: *image.YCbCr not the same 16294 pixels
different 14.73%
resize_test.go:377: *image.YCbCr PSNR 59.0534
resize_test.go:382: *image.YCbCr not the same 16413 pixels
different 14.84%
Change-Id: Ia8c578a53416ec0f1cac1477a1a68acfede84b24
2015-09-04 22:54:31 +00:00
|
|
|
t.Logf("%v PSNR %.4f", imTypes[i], res.psnr)
|
2013-12-07 20:05:18 +00:00
|
|
|
}
|
|
|
|
s := im1.Bounds().Size()
|
|
|
|
tot := s.X * s.Y
|
|
|
|
if per := float32(100*res.diffCnt) / float32(tot); per > maxPixelDiffPercentage {
|
pkg/images/resize: show that golang.org/x/image/draw is a win
While investigating issue #635 I remembered that golang.org/x/image/draw
might offer some interesting features. It indeed happens to have some
rescaling routines that seem to work better in the YCbCr case than our
custom code, which is illustrated by these benchmarks:
% go test -v -bench Benchmark.*YCrCb.* -run Bench* -benchmem
% ./pkg/images/resize/
PASS
BenchmarkResizeYCrCb-4 20 79213653 ns/op
9437475 B/op 5 allocs/op
BenchmarkNewResizeYCrCb-4 100 15711294 ns/op
1048668 B/op 2 allocs/op
BenchmarkHalveYCrCb-4 100 17328467 ns/op
128 B/op 1 allocs/op
ok camlistore.org/pkg/images/resize 5.889s
One can see that not only the new resize is faster, and uses less memory
than the old one, but it is also about as fast as "resizing by halving
in place". And this is with the ApproxBiLinear algorithm; some quick
additional tests seemed to indicate that NearestNeighbor was twice as
fast, with about the same memory usage. I chose ApproxBiLinear as it
seemed the most conservative choice for now.
I think it is also worth investigating whether we can be rid of "halving
in place", since it would make for simpler code overall, and since
ApproxBiLinear might be faster in most cases. It would have the nice
side-effect of solving issue #635 too. However, "halving in place" will
always win when it comes to memory usage, so it depends on our
priorities.
Finally, these other new benchmarks show that using the new resize does
not make the #635 mystery much worse (going from ~16% to ~18%), and that
interestingly the results of the old resize and the new resize are
pretty different by themselves.
% go test -v -run TestCompare ./pkg/images/resize/
=== RUN TestCompareOldResizeToHalveInplace
--- FAIL: TestCompareOldResizeToHalveInplace (2.49s)
resize_test.go:377: *image.Gray PSNR 63.7793
resize_test.go:377: *image.Gray16 PSNR 59.9547
resize_test.go:377: *image.NRGBA PSNR 62.8252
resize_test.go:377: *image.NRGBA64 PSNR 62.8252
resize_test.go:377: *image.Paletted PSNR 51.4949
resize_test.go:377: *image.RGBA PSNR 62.8252
resize_test.go:377: *image.RGBA64 PSNR 62.8252
resize_test.go:377: *image.YCbCr PSNR 61.9664
resize_test.go:382: *image.YCbCr not the same 18077 pixels
different 16.35%
resize_test.go:377: *image.YCbCr PSNR 52.4121
resize_test.go:382: *image.YCbCr not the same 18139 pixels
different 16.40%
resize_test.go:377: *image.YCbCr PSNR 51.4972
resize_test.go:382: *image.YCbCr not the same 17932 pixels
different 16.21%
resize_test.go:377: *image.YCbCr PSNR 51.6399
resize_test.go:382: *image.YCbCr not the same 17881 pixels
different 16.17%
resize_test.go:377: *image.YCbCr PSNR 50.7736
resize_test.go:382: *image.YCbCr not the same 17976 pixels
different 16.25%
resize_test.go:377: *image.YCbCr PSNR 52.4536
resize_test.go:382: *image.YCbCr not the same 18180 pixels
different 16.44%
=== RUN TestCompareNewResizeToHalveInplace
--- FAIL: TestCompareNewResizeToHalveInplace (2.27s)
resize_test.go:377: *image.Gray PSNR 63.7793
resize_test.go:377: *image.Gray16 PSNR 59.9547
resize_test.go:377: *image.NRGBA PSNR 62.8252
resize_test.go:377: *image.NRGBA64 PSNR 62.8252
resize_test.go:377: *image.Paletted PSNR 51.4949
resize_test.go:377: *image.RGBA PSNR 62.8252
resize_test.go:377: *image.RGBA64 PSNR 62.8252
resize_test.go:377: *image.YCbCr PSNR 59.5902
resize_test.go:382: *image.YCbCr not the same 20757 pixels
different 18.77%
resize_test.go:377: *image.YCbCr PSNR 52.0962
resize_test.go:382: *image.YCbCr not the same 20811 pixels
different 18.82%
resize_test.go:377: *image.YCbCr PSNR 51.3374
resize_test.go:382: *image.YCbCr not the same 20671 pixels
different 18.69%
resize_test.go:377: *image.YCbCr PSNR 51.3586
resize_test.go:382: *image.YCbCr not the same 20618 pixels
different 18.64%
resize_test.go:377: *image.YCbCr PSNR 57.2346
resize_test.go:382: *image.YCbCr not the same 20705 pixels
different 18.72%
resize_test.go:377: *image.YCbCr PSNR 50.7504
resize_test.go:382: *image.YCbCr not the same 20847 pixels
different 18.85%
=== RUN TestCompareOldResizeToNewResize
--- FAIL: TestCompareOldResizeToNewResize (2.54s)
resize_test.go:377: *image.Gray PSNR +Inf
resize_test.go:377: *image.Gray16 PSNR +Inf
resize_test.go:377: *image.NRGBA PSNR +Inf
resize_test.go:377: *image.NRGBA64 PSNR +Inf
resize_test.go:377: *image.Paletted PSNR +Inf
resize_test.go:377: *image.RGBA PSNR +Inf
resize_test.go:377: *image.RGBA64 PSNR +Inf
resize_test.go:377: *image.YCbCr PSNR 59.1024
resize_test.go:382: *image.YCbCr not the same 16350 pixels
different 14.78%
resize_test.go:377: *image.YCbCr PSNR 62.6523
resize_test.go:377: *image.YCbCr PSNR 62.7010
resize_test.go:377: *image.YCbCr PSNR 59.1396
resize_test.go:382: *image.YCbCr not the same 16225 pixels
different 14.67%
resize_test.go:377: *image.YCbCr PSNR 59.0844
resize_test.go:382: *image.YCbCr not the same 16294 pixels
different 14.73%
resize_test.go:377: *image.YCbCr PSNR 59.0534
resize_test.go:382: *image.YCbCr not the same 16413 pixels
different 14.84%
Change-Id: Ia8c578a53416ec0f1cac1477a1a68acfede84b24
2015-09-04 22:54:31 +00:00
|
|
|
t.Errorf("%v not the same %d pixels different %.2f%%", imTypes[i], res.diffCnt, per)
|
2013-12-07 20:05:18 +00:00
|
|
|
}
|
|
|
|
}
|
2015-11-23 22:16:18 +00:00
|
|
|
}
|
2013-12-07 20:05:18 +00:00
|
|
|
|
2015-11-23 22:16:18 +00:00
|
|
|
// TODO(mpl): refactor with testCompareResizeMethods later
|
|
|
|
func testCompareWithResized(t *testing.T, resizeMethod string) {
|
|
|
|
images1, images2 := []image.Image{}, []image.Image{}
|
|
|
|
var imTypes []string
|
|
|
|
for _, im := range makeImages(testIm.Bounds()) {
|
|
|
|
// keeping track of the types for the final output
|
|
|
|
imgType := fmt.Sprintf("%T", im)
|
|
|
|
imgType = imgType[strings.Index(imgType, ".")+1:]
|
|
|
|
if m, ok := im.(*image.YCbCr); ok {
|
|
|
|
imgType += "." + m.SubsampleRatio.String()
|
|
|
|
}
|
|
|
|
imTypes = append(imTypes, imgType)
|
|
|
|
fillTestImage(im)
|
|
|
|
images1 = append(images1, im)
|
|
|
|
}
|
|
|
|
for _, im := range makeImages(testIm.Bounds()) {
|
|
|
|
fillTestImage(im)
|
|
|
|
images2 = append(images2, resizeMethods[resizeMethod](im))
|
|
|
|
}
|
|
|
|
var (
|
|
|
|
f io.WriteCloser
|
|
|
|
err error
|
|
|
|
)
|
|
|
|
if *flagOutput != "" {
|
|
|
|
os.Mkdir(*flagOutput, os.FileMode(0777))
|
|
|
|
f, err = os.Create(filepath.Join(*flagOutput, "index.html"))
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
defer f.Close()
|
|
|
|
fmt.Fprintf(f, `<!DOCTYPE html>
|
|
|
|
<html lang="en">
|
|
|
|
<head>
|
|
|
|
<meta charset="utf-8">
|
|
|
|
<title>Image comparison for original image vs image resized with `+resizeMethod+`</title>
|
|
|
|
</head>
|
|
|
|
<body style="background-color: grey">
|
|
|
|
<table>
|
|
|
|
`)
|
|
|
|
}
|
|
|
|
for i, im1 := range images1 {
|
|
|
|
im2 := images2[i]
|
|
|
|
res := compareImages(im1, im2, true)
|
|
|
|
if *flagOutput != "" {
|
|
|
|
fmt.Fprintf(f, "<tr>")
|
|
|
|
fn := getFilename(imTypes[i], "ori")
|
|
|
|
err := savePng(t, im1, fn)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
fmt.Fprintf(f, `<td><img src="%s"><br>%s`, fn, fn)
|
|
|
|
|
|
|
|
fn = getFilename(imTypes[i], resizeMethod)
|
|
|
|
err = savePng(t, im2, fn)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
fmt.Fprintf(f, `<td><img src="%s"><br>%s`, fn, fn)
|
|
|
|
|
|
|
|
if res.diffIm != nil {
|
|
|
|
fn = getFilename(imTypes[i], "diff")
|
|
|
|
err = savePng(t, res.diffIm, fn)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
fmt.Fprintf(f, `<td><img src="%s"><br>%s`, fn, fn)
|
|
|
|
}
|
|
|
|
fmt.Fprintln(f)
|
|
|
|
}
|
|
|
|
|
|
|
|
if res.psnr < psnrThreshold {
|
|
|
|
t.Errorf("%v PSNR too low %.4f", imTypes[i], res.psnr)
|
|
|
|
} else {
|
|
|
|
t.Logf("%v PSNR %.4f", imTypes[i], res.psnr)
|
|
|
|
}
|
|
|
|
s := im1.Bounds().Size()
|
|
|
|
tot := s.X * s.Y
|
|
|
|
if per := float32(100*res.diffCnt) / float32(tot); per > maxPixelDiffPercentage {
|
|
|
|
t.Errorf("%v not the same %d pixels different %.2f%%", imTypes[i], res.diffCnt, per)
|
|
|
|
}
|
|
|
|
}
|
2013-12-07 20:05:18 +00:00
|
|
|
}
|