package main
import (
"errors"
"fmt"
"strconv"
"strings"
)
type point struct {
x int
y int
value int
}
type image struct {
w int
h int
allPoint int
points [][]*point
}
func (i *image) newImage(m, n int) *image {
img := make([][]*point, m)
for i1 := 0; i1 < m; i1++ {
img[i1] = make([]*point, n)
for j := 0; j < n; j++ {
itemPoint := &point{
x: i1,
y: j,
value: 0,
}
img[i1][j] = itemPoint
}
}
return &image{
w: m,
h: n,
allPoint: m * n,
points: img,
}
}
func (i *image) getPointValue(x, y int) (int, error) {
for i1 := 0; i1 < i.w; i1++ {
for j := 0; j < i.h; j++ {
if i1 == x && j == y {
return i.points[i1][j].value, nil
}
}
}
return 0, errors.New("not found")
}
func (i *image) setPointValue(p1 *point) (*image, error) {
for i1 := 0; i1 < i.w; i1++ {
for j := 0; j < i.h; j++ {
if i1 == p1.x && j == p1.y {
i.points[i1][j].value = p1.value
return i, nil
}
}
}
return nil, errors.New("not found")
}
func (i *image) setPointsValue(list []*point, value int) {
for _, p := range list {
p.value = value
i.setPointValue(p)
}
}
func (i *image) countWaitePoints() (count int) {
for i1 := 0; i1 < i.w; i1++ {
for j := 0; j < i.h; j++ {
if i.points[i1][j].value == 1 {
count++
}
}
}
return
}
func (i *image) isAllWaite() bool {
if i.countWaitePoints() == i.allPoint {
return true
}
return false
}
// 获取一个点周围的非白色像素点
func (i *image) listAroundNotWaitePoints(p1 *point) []*point {
list := make([]*point, 0)
centerX, centreY := p1.x, p1.y
for x := -1; x <= 1; x++ {
for y := -1; y <= 1; y++ {
if x != 0 && y != 0 {
continue
}
itemX := centerX + x
itemY := centreY + y
//溢出
if itemX*itemY < 0 {
continue
}
if value, err := i.getPointValue(itemX, itemY); err == nil {
if value != 1 {
list = append(list, &point{
x: itemX,
y: itemY,
value: i.points[itemX][itemY].value,
})
}
}
}
}
return list
}
func (i *image) listWaitePoints() []*point {
list := make([]*point, 0)
for i1 := 0; i1 < i.w; i1++ {
for j := 0; j < i.h; j++ {
if i.points[i1][j].value == 1 {
list = append(list, &point{
x: i1,
y: j,
value: i.points[i1][j].value,
})
}
}
}
return list
}
func (i *image) timer(count int) int {
if i.isAllWaite() {
return count
} else {
count++
waitePoints := i.listWaitePoints()
for _, waitePoint := range waitePoints {
//开始膨胀
if notWaitePoints := i.listAroundNotWaitePoints(waitePoint); len(notWaitePoints) > 0 {
i.setPointsValue(notWaitePoints, 1)
}
}
return i.timer(count)
}
}
func main() {
var inputStr string
fmt.Scan(&inputStr)
inputStrList := strings.Split(inputStr, ",")
inputIntList := make([]int, len(inputStrList))
for i, s2 := range inputStrList {
inputIntList[i], _ = strconv.Atoi(s2)
}
var m, n int
m = inputIntList[0]
n = inputIntList[1]
myImage := new(image)
img := myImage.newImage(m, n)
img.setPointValue(&point{
x: inputIntList[2],
y: inputIntList[3],
value: 1,
})
img.setPointValue(&point{
x: inputIntList[4],
y: inputIntList[5],
value: 1,
})
count := img.timer(0)
fmt.Println(count)
}
总结:矩阵扩散在图形图像中被称为膨胀,结合openCV中对图片和像素点的定义,在程序中我定义了两种struct: image 和point,并实现了膨胀系数为1的膨胀算法。在通过递归的方式不断执行膨胀操作,知道全部点都变白,则停止递归,每次膨胀时计数器timer加一,递归结束后返回timer.