images_test.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. package imageproc
  2. import (
  3. "image"
  4. "image/color"
  5. "image/draw"
  6. "reflect"
  7. "testing"
  8. )
  9. func createImage(width, height int, fillCol color.RGBA) image.Image {
  10. img := image.NewRGBA(image.Rect(0, 0, width, height))
  11. draw.Draw(img, img.Bounds(), &image.Uniform{fillCol}, image.Point{}, draw.Src)
  12. return img
  13. }
  14. func TestComposite(t *testing.T) {
  15. tests := []struct {
  16. name string
  17. img image.Image
  18. expectedRGBA color.RGBA
  19. }{
  20. {
  21. name: "Transparent image",
  22. img: createImage(5, 5, color.RGBA{0, 0, 0, 0}),
  23. expectedRGBA: color.RGBA{255, 255, 255, 255},
  24. },
  25. {
  26. name: "Solid red image",
  27. img: createImage(5, 5, color.RGBA{255, 0, 0, 255}),
  28. expectedRGBA: color.RGBA{255, 0, 0, 255},
  29. },
  30. }
  31. for _, tt := range tests {
  32. t.Run(tt.name, func(t *testing.T) {
  33. resultImg := Composite(tt.img)
  34. // Check the pixel values in the resulting image
  35. for x := range resultImg.Bounds().Dx() {
  36. for y := range resultImg.Bounds().Dy() {
  37. r, g, b, a := resultImg.At(x, y).RGBA()
  38. expectedR, expectedG, expectedB, expectedA := tt.expectedRGBA.RGBA()
  39. if r != expectedR || g != expectedG || b != expectedB || a != expectedA {
  40. t.Errorf("Pixel mismatch at (%d, %d): got (%d, %d, %d, %d), want (%d, %d, %d, %d)",
  41. x, y, r, g, b, a, expectedR, expectedG, expectedB, expectedA)
  42. }
  43. }
  44. }
  45. })
  46. }
  47. }
  48. func TestResize(t *testing.T) {
  49. tests := []struct {
  50. name string
  51. img image.Image
  52. newSize image.Point
  53. method int
  54. expected image.Point
  55. }{
  56. {
  57. name: "Resize with bilinear interpolation",
  58. img: createImage(5, 5, color.RGBA{255, 0, 0, 255}),
  59. newSize: image.Point{10, 10},
  60. method: ResizeBilinear,
  61. expected: image.Point{10, 10},
  62. },
  63. {
  64. name: "Resize with nearest neighbor",
  65. img: createImage(10, 10, color.RGBA{0, 255, 0, 255}),
  66. newSize: image.Point{5, 5},
  67. method: ResizeNearestNeighbor,
  68. expected: image.Point{5, 5},
  69. },
  70. {
  71. name: "Resize with catmullrom",
  72. img: createImage(1024, 1024, color.RGBA{0, 0, 255, 255}),
  73. newSize: image.Point{10, 10},
  74. method: ResizeCatmullrom,
  75. expected: image.Point{10, 10},
  76. },
  77. {
  78. name: "Resize with approx bilinear",
  79. img: createImage(1024, 768, color.RGBA{100, 100, 100, 255}),
  80. newSize: image.Point{4, 3},
  81. method: ResizeApproxBilinear,
  82. expected: image.Point{4, 3},
  83. },
  84. }
  85. for _, tt := range tests {
  86. t.Run(tt.name, func(t *testing.T) {
  87. resizedImg := Resize(tt.img, tt.newSize, tt.method)
  88. if resizedImg.Bounds().Dx() != tt.expected.X || resizedImg.Bounds().Dy() != tt.expected.Y {
  89. t.Errorf("Unexpected size for resized image: got (%d, %d), want (%d, %d)",
  90. resizedImg.Bounds().Dx(), resizedImg.Bounds().Dy(), tt.expected.X, tt.expected.Y)
  91. }
  92. })
  93. }
  94. }
  95. func TestResizeInvalidMethod(t *testing.T) {
  96. defer func() {
  97. if r := recover(); r == nil {
  98. t.Errorf("Expected panic for invalid resizing method, but did not panic")
  99. }
  100. }()
  101. img := createImage(10, 10, color.RGBA{0, 0, 0, 255})
  102. Resize(img, image.Point{5, 5}, -1)
  103. }
  104. func TestNormalize(t *testing.T) {
  105. tests := []struct {
  106. name string
  107. img image.Image
  108. mean [3]float32
  109. std [3]float32
  110. rescale bool
  111. channelFirst bool
  112. expected []float32
  113. }{
  114. {
  115. name: "Rescale with channel first",
  116. img: createImage(2, 2, color.RGBA{128, 128, 128, 255}),
  117. mean: ImageNetStandardMean,
  118. std: ImageNetStandardSTD,
  119. rescale: true,
  120. channelFirst: true,
  121. expected: []float32{
  122. 0.003921628, 0.003921628, 0.003921628, 0.003921628, // R values
  123. 0.003921628, 0.003921628, 0.003921628, 0.003921628, // G values
  124. 0.003921628, 0.003921628, 0.003921628, 0.003921628, // B values
  125. },
  126. },
  127. {
  128. name: "Rescale without channel first",
  129. img: createImage(2, 2, color.RGBA{255, 0, 0, 255}),
  130. mean: [3]float32{0.0, 0.0, 0.0},
  131. std: [3]float32{1.0, 1.0, 1.0},
  132. rescale: true,
  133. channelFirst: false,
  134. expected: []float32{
  135. 1.0, 0.0, 0.0,
  136. 1.0, 0.0, 0.0,
  137. 1.0, 0.0, 0.0,
  138. 1.0, 0.0, 0.0,
  139. },
  140. },
  141. {
  142. name: "No rescale with mean/std adjustment",
  143. img: createImage(2, 2, color.RGBA{100, 150, 200, 255}),
  144. mean: ClipDefaultMean,
  145. std: ClipDefaultSTD,
  146. rescale: false,
  147. channelFirst: false,
  148. expected: []float32{
  149. -1.7922626, -1.7520971, -1.4802198,
  150. -1.7922626, -1.7520971, -1.4802198,
  151. -1.7922626, -1.7520971, -1.4802198,
  152. -1.7922626, -1.7520971, -1.4802198,
  153. },
  154. },
  155. }
  156. for _, tt := range tests {
  157. t.Run(tt.name, func(t *testing.T) {
  158. result := Normalize(tt.img, tt.mean, tt.std, tt.rescale, tt.channelFirst)
  159. if !reflect.DeepEqual(result, tt.expected) {
  160. t.Errorf("Test %s failed: got %v, want %v", tt.name, result, tt.expected)
  161. }
  162. })
  163. }
  164. }