图像中部分RGB矩阵可视化

图像中部分RGB可视化

今天室友有个需求就是模仿下面这张图画个示意图:

大致就是把图像中的一小部分区域的RGB值可视化了一下。他居然不知道该怎么画,我寻思这不直接秒了。

python 复制代码
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt


class Plotter:
    def __init__(self, img):
        self.img = img
        self.range = None

        # 三个图的位置
        self.loc = [
            [0.01, 0.325, 0.35, 0.35],
            [0.375, 0.375, 0.25, 0.25],
            [0.71, 0.355, 0.29, 0.29],
        ]
        self.dloc = [0.02, 0.02]  # 表格间距
        self.facecolor = plt.get_cmap("Accent")(range(3))  # 表格颜色

    def plot_img(self, fig):
        img_range = self.range
        axes = fig.add_axes(self.loc[0])
        axes.imshow(self.img, aspect="auto")
        axes.add_patch(
            plt.Rectangle(
                (img_range[0], img_range[2]),
                img_range[1] - img_range[0],
                img_range[3] - img_range[2],
                fill=False,
                edgecolor="red",
                linewidth=2,
            )
        )
        axes.axis("off")

    def plot_table(self, fig, table):
        loc = self.loc[2]
        dloc = self.dloc
        facecolor = self.facecolor

        for i in range(table.shape[2]):
            axes = fig.add_axes(
                [loc[0] - dloc[0] * i, loc[1] - dloc[1] * i, loc[2], loc[3]],
            )
            axes.table(
                cellText=table[:, :, i],
                loc="center",
                cellColours=np.full(
                    (table.shape[0], table.shape[1], 4),
                    facecolor[i],
                    dtype=self.facecolor[0].dtype,
                ),
                bbox=[0, 0, 1, 1],
            )
            axes.axis("off")

    def plot_range_img(self, fig, range_img):
        axes = fig.add_axes(self.loc[1])
        axes.imshow(range_img, aspect="auto")

        axes.set_xticks([])
        axes.set_yticks([])
        spines = ["left", "right", "bottom", "top"]
        for spine in spines:
            axes.spines[spine].set_color("r")

    def plot_path(self, axes, x1, x2):
        x = np.linspace(x1[0], x2[0], 100)
        y = np.linspace(x1[1], x2[1], 100)
        axes.set_xlim(0, 1)
        axes.set_ylim(0, 1)
        axes.plot(x, y, "r--")

    def range_points_on_img(self):
        img_range = self.range
        loc = self.loc[0]
        luloc = loc[0] + img_range[0] / self.img.shape[0] * loc[2]
        # axes坐标系y轴方向相反
        ldloc = loc[1] + (self.img.shape[1] - img_range[2]) / self.img.shape[1] * loc[3]
        dx = (img_range[1] - img_range[0]) / self.img.shape[0] * loc[2]
        dy = (img_range[3] - img_range[2]) / self.img.shape[1] * loc[3]
        return [(luloc + dx, ldloc - dy), (luloc + dx, ldloc)]

    def plot_img2range(self, axes):
        img_points = self.range_points_on_img()
        range_points = [
            (self.loc[1][0], self.loc[1][1]),
            (self.loc[1][0], self.loc[1][1] + self.loc[1][3]),
        ]
        print(img_points)
        self.plot_path(axes, img_points[0], range_points[0])
        self.plot_path(axes, img_points[1], range_points[1])

    def plot_range2table(self, axes):
        range_points = [
            (self.loc[1][0] + self.loc[1][2], self.loc[1][1]),
            (self.loc[1][0] + self.loc[1][2], self.loc[1][1] + self.loc[1][3]),
        ]
        table_points = [
            (self.loc[2][0] - self.dloc[0] * 2, self.loc[2][1] - self.dloc[1] * 2),
            (
                self.loc[2][0] - self.dloc[0] * 2,
                self.loc[2][1] + self.loc[2][3] - self.dloc[1] * 2,
            ),
        ]
        self.plot_path(axes, range_points[0], table_points[0])
        self.plot_path(axes, range_points[1], table_points[1])

    def plot_line(self, fig):
        axes = fig.add_axes([0, 0, 1, 1])
        self.plot_img2range(axes)
        self.plot_range2table(axes)
        axes.axis("off")

    def plot(self, img_range):
        self.range = img_range
        range_img = self.img[
            img_range[0] : img_range[1], img_range[2] : img_range[3], :
        ]
        fig = plt.figure()
        self.plot_img(fig)
        self.plot_range_img(fig, range_img)
        self.plot_table(fig, range_img)
        self.plot_line(fig)
        plt.show()


if __name__ == "__main__":
    img_path = "lena_color_512.tif"
    img = cv.imread(img_path, cv.IMREAD_UNCHANGED)
    img = cv.cvtColor(img, cv.COLOR_BGR2RGB)
    p = Plotter(img)
    p.plot([255, 265, 255, 265])

其实就是先画三个主图,一个全部的,一个小范围内的,一个RGB值的表,然后画四根线就完事了。效果如下:

唯一要注意的是 Axes 坐标系和图像的坐标系中Y轴是相反的,然后其他 axes.imshowaxes.table 都让它填满整个 Axes 就好了,要不然它给你自适应了,不好算几根连线的位置。

这里写的时候没想好,按 copilot 生成的 img_range 形式写下去了,目前是 [x起点,x终点,y起点,y终点] 的格式,换成 [x起点,y起点,x范围,y范围] 会更统一一点。但也懒得改了,一小时的工作时间白嫖室友一顿必胜客,很舒服。

相关推荐
Patrick在香港16 小时前
Python 拉取城巴开放数据:406 条路线,香港岛巴士网络的数字画像
网络·python·数据分析·php·数据可视化·香港·开放数据
AndrewHZ17 小时前
图像处理入门020 | 图像二值化:阈值分割基础 —— cv2.threshold 五种类型与自适应阈值铺垫
图像处理·opencv·文档扫描·阈值分割·图像二值化·trackbar·自适应阈值
笑霸final19 小时前
不用上传服务器!用 Vue3 + ONNX Runtime Web 在浏览器本地实现智能抠图
运维·前端·图像处理·ai·onnx·canva可画·web性能优化
躺柒21 小时前
读数据可视化18时变数据(下)
信息可视化·时序数据库·可视化·数据可视化·实时数据库·时变数据
十三画者1 天前
【文献分享】CancerCellNet:评估癌症模型转录保真度的计算工具
人工智能·深度学习·数据挖掘·数据分析·数据可视化
躺柒1 天前
读数据可视化17时变数据(上)
信息可视化·时序数据库·可视化·数据可视化·时变数据·时变
桃西西呀2 天前
「百年一遇」的台风,为什么我这辈子就遇了好几回?概率论把这笔账算给你看
人工智能·python·数据可视化
A hao2 天前
户外LED广告牌需要什么防护等级IP级别?
大数据·网络·图像处理·人工智能·网络协议·tcp/ip·广告
一只嵌入式爱好者2 天前
深入理解ISP
图像处理·isp
sali-tec2 天前
C# 基于OpenCv的视觉工作流-章106-差值追踪
图像处理·人工智能·opencv·算法·计算机视觉