华为OD机试真题】68、矩阵扩散

Go 复制代码
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.

相关推荐
取个名字真难呐1 小时前
矩阵乘法实现获取第i行,第j列值,矩阵大小不变
python·线性代数·矩阵·numpy
浪里个浪的10245 小时前
【C语言】从3x5矩阵计算前三行平均值并扩展到4x5矩阵
c语言·开发语言·矩阵
phoenix@Capricornus6 小时前
矩阵的对角化&特征值分解
图像处理·线性代数·机器学习·矩阵
浪里个浪的10246 小时前
【C语言】计算3x3矩阵每行的最大值并存入第四列
c语言·开发语言·矩阵
小喵要摸鱼6 小时前
MATLAB 使用教程 —— 矩阵和数组
matlab·矩阵
金星娃儿6 小时前
MATLAB基础知识笔记——(矩阵的运算)
笔记·matlab·矩阵
phoenix@Capricornus12 小时前
循环矩阵和BCCB矩阵与向量乘积的快速计算——矩阵向量乘积与频域乘积之间的转换
线性代数·矩阵
Deepcong2 天前
多个摄像机画面融合:找到同一个目标在多个画面中的伪三维坐标,找出这几个摄像头间的转换矩阵
人工智能·线性代数·矩阵
雷达学弱狗3 天前
右旋圆极化散射后的stocks矢量 与T3矩阵的关系
线性代数·矩阵
不穿铠甲的穿山甲3 天前
glsl中vec4是行矩阵还是列矩阵
线性代数·矩阵