robocar-steering/pkg/steering/bbox_test.go
2022-08-21 22:35:02 +02:00

164 lines
3.7 KiB
Go

package steering
import (
"encoding/json"
"fmt"
"gocv.io/x/gocv"
"image"
"image/color"
_ "image/jpeg"
"os"
"reflect"
"testing"
)
type ObjectsList struct {
BBoxes []BBox `json:"bboxes"`
}
type BBox struct {
Left float32 `json:"left"`
Top float32 `json:"top"`
Bottom float32 `json:"bottom"`
Right float32 `json:"right"`
Confidence float32 `json:"confidence"`
}
func (bb *BBox) toRect(imgWidth, imgHeight int) image.Rectangle {
return image.Rect(
int(bb.Left*float32(imgWidth)),
int(bb.Top*float32(imgHeight)),
int(bb.Right*float32(imgWidth)),
int(bb.Bottom*float32(imgHeight)),
)
}
func load_data(dataName string) (*gocv.Mat, []BBox, error) {
contentBBoxes, err := os.ReadFile(fmt.Sprintf("test_data/bboxes-%s.json", dataName))
if err != nil {
return nil, []BBox{}, fmt.Errorf("unable to load json file for bbox of '%v': %w", dataName, err)
}
var obj ObjectsList
err = json.Unmarshal(contentBBoxes, &obj)
if err != nil {
return nil, []BBox{}, fmt.Errorf("unable to unmarsh json file for bbox of '%v': %w", dataName, err)
}
imgContent, err := os.ReadFile(fmt.Sprintf("test_data/img-%s.jpg", dataName))
if err != nil {
return nil, []BBox{}, fmt.Errorf("unable to load jpg file of '%v': %w", dataName, err)
}
img, err := gocv.IMDecode(imgContent, gocv.IMReadUnchanged)
if err != nil {
return nil, []BBox{}, fmt.Errorf("unable to load jpg of '%v': %w", dataName, err)
}
return &img, obj.BBoxes, nil
}
func drawImage(img *gocv.Mat, bboxes []BBox) {
for _, bb := range bboxes {
gocv.Rectangle(img, bb.toRect(img.Cols(), img.Rows()), color.RGBA{R: 0, G: 255, B: 0, A: 0}, 2)
gocv.PutText(
img,
fmt.Sprintf("%.2f", bb.Confidence),
image.Point{
X: int(bb.Left*float32(img.Cols()) + 10.),
Y: int(bb.Top*float32(img.Rows()) + 10.),
},
gocv.FontHersheyTriplex,
0.4,
color.RGBA{R: 0, G: 0, B: 0, A: 0},
1)
}
}
func saveImage(name string, img *gocv.Mat) error {
err := os.MkdirAll("test_result", os.ModePerm)
if err != nil {
return fmt.Errorf("unable to create directory for test result: %w", err)
}
jpg, err := gocv.IMEncode(gocv.JPEGFileExt, *img)
if err != nil {
return fmt.Errorf("unable to encode jpg image: %w", err)
}
defer jpg.Close()
err = os.WriteFile(fmt.Sprintf("test_result/%s.jpg", name), jpg.GetBytes(), os.ModePerm)
if err != nil {
return fmt.Errorf("unable to write jpeg file: %w", err)
}
return nil
}
func DisplayImageAndBBoxes(dataName string) error {
img, bboxes, err := load_data(dataName)
if err != nil {
return fmt.Errorf("unable to load image and bboxes: %w", err)
}
drawImage(img, bboxes)
err = saveImage(dataName, img)
if err != nil {
return fmt.Errorf("unable to save image: %w", err)
}
return nil
}
func TestDisplayBBox(t *testing.T) {
type args struct {
dataName string
}
tests := []struct {
name string
args args
//want []*image.Rectangle
}{
{
name: "default",
args: args{dataName: "01"},
},
{
name: "02",
args: args{dataName: "02"},
},
{
name: "03",
args: args{dataName: "03"},
},
{
name: "04",
args: args{dataName: "04"},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := DisplayImageAndBBoxes(tt.args.dataName)
if err != nil {
t.Errorf("unable to draw image: %v", err)
}
})
}
}
func TestGroupBBoxes(t *testing.T) {
type args struct {
bboxes []*image.Rectangle
}
tests := []struct {
name string
args args
want []*image.Rectangle
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := GroupBBoxes(tt.args.bboxes); !reflect.DeepEqual(got, tt.want) {
t.Errorf("GroupBBoxes() = %v, want %v", got, tt.want)
}
})
}
}