golang ---image--热力图与照片的重叠

热力图是通过摄像头获取的

热力图的数据本身是一个温度数据的矩阵(二维数组),代表热力图上每个点的数据。
下图是一个数组,里面都是一个点的温度值。
在这里插入图片描述

下面两张图就是一个二维数组,将上方的数组经过一定的算法处理之后,得到一个二维数组,每个点就基本直接代表热力图的每个像素代表的温度,这里是一个160*120的矩阵,也就是这个热力图长宽比就是160:120
在这里插入图片描述在这里插入图片描述
该图片我是打了马赛克的,大概的样子也就是这样了
在这里插入图片描述

func ChangeImg(rgbMapArr [160][120]float64, max, min float64) {

	imgfile, err := os.Open("./1653982887954641200.jpeg")//照片
	if err != nil {
		fmt.Println(err.Error())
	}
	defer imgfile.Close()

	backgroud, err := jpeg.Decode(imgfile)
	if err != nil {
		fmt.Println(err.Error())
	}
	backgroudCImg := NewMyImg(backgroud)
	bounds := backgroud.Bounds()
	xd := bounds.Dx()//照片的y方向的边界
	yd := bounds.Dy()//照片的x方向的边界
	image3 := image.NewRGBA(backgroud.Bounds())//这里通过新画一个图,在这个图上通过计算照片和热力图每个对应点的rgba后再渲染到这个新的图上
	for x := 0; x < xd; x++ { //这里的两个for循环就是在从照片的第一个点开始遍历,遍历每一个点,图片本身我们可以看出就是一个很多个像素点组成,也就是一个二维数组,图片就像是放在直角坐标系的第四象限里面的
		for y := 0; y < yd; y++ {
			r1, g1, b1, a1 := backgroudCImg.At(x, y).RGBA()//获取每个像素点的rgba数据
			//这里是因为热力图的比例小于照片,为了更加贴合照片,我们需要按照一定的比例改变照片的颜色,这里热力图的一个点相当于照片16.2个点,也就是照片的对应的16.2个点都要使用热力图的这对应的一个点的rgba数据来改变
			hx := int(math.Round(float64(x) / 16.2)) 
			hy := int(math.Round(float64(y) / 16.2))
			if hy == 120 {
				hy = 119
			}
			if hx == 160 {
				hx = 159
			}
			rgbMap := coverToData(rgbMapArr[hx][hy], max, min)//通过一个温度值,以及当前这组温度的最大值和最小值来得到,这个温度对应的rgb值
			image3.SetRGBA64(x, y, color.RGBA64{//改变图片的rgba值
				R: uint16((r1 + uint32(rgbMap["R"])*256) / 2),
				G: uint16((g1 + uint32(rgbMap["G"])*256) / 2),
				B: uint16((b1 + uint32(rgbMap["B"])*256) / 2),
				A: uint16(a1),
			})
		}
	}

	out, _ := os.Create("./result2.jpeg")
	if err != nil {
		log.Fatalf("failed to create: %s", err)
	}
	jpeg.Encode(out, image3, &jpeg.Options{jpeg.DefaultQuality})
	defer out.Close()
}
type MyImg struct {
	image.Image
	custom sync.Map
}


func NewMyImg(img image.Image) *MyImg {
	return &MyImg{img, sync.Map{}}
}


func (m *MyImg) Set(x, y int, c color.Color) {
	m.custom.Store(image.Point{x, y}, c)
}

func (m *MyImg) At(x, y int) color.Color {
	// Explicitly changed part: custom colors of the changed pixels:
	if c, ok := m.custom.Load(image.Point{x, y}); c != nil && ok {
		return c.(color.Color)
	}
	// Unchanged part: colors of the original image:
	return m.Image.At(x, y)
}
func coverToData(data, max, min float64) map[string]int {
	result := make(map[string]int)
	result["R"] = 0
	result["G"] = 0
	result["B"] = 0

	//max := max
	//min := min
	ranges := max - min + 1
	if data < min {
		return result
	}
	if data > max {
		result["R"] = 255
		result["G"] = 255
		result["B"] = 255
		return result
	}
	r := (data - min) / ranges
	step := ranges / 5
	idx := int(r * 5)
	h := (float64(idx)+1.0)*step + min
	m := float64(idx)*step + min
	localR := (data - m) / (h - m)

	switch idx {
	case 0: //蓝色-青色
		result["R"] = 0
		result["G"] = int(localR * 255)
		result["B"] = 255
		return result
	case 1: //绿色-青色
		result["R"] = 0
		result["G"] = 255
		result["B"] = int((1 - localR) * 255)
		return result
	case 2: //绿色-橙色
		result["R"] = int(localR * 255)
		result["G"] = 255
		result["B"] = 0
		return result
	case 3: //红色-橙色
		result["R"] = 255
		result["G"] = int((1 - localR) * 255)
		result["B"] = 0
		return result
	case 4: //红色-紫色
		result["R"] = 255
		result["G"] = 0
		result["B"] = int(localR * 255)
		return result
	}
	return result
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值