吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 989|回复: 0
收起左侧

[Python 原创] 图片上点的坐标标记

[复制链接]
hzy008 发表于 2023-8-14 23:28
[ 本帖最后由 wushaominkk 于 2023-8-17 08:44 编辑 ]\n\n[ 本帖最后由 hzy008 于 2023-8-14 23:43 编辑 ]\n\n
(第一次发帖)
功能:可以读取指定文件夹中的全部图片,对每一张图片都可以标记坐标轴并显示图片大小,点击鼠标,会出现一个点,这个标记点可以选择不同的颜色和大小,标记点会有坐标提示,当标记完成后,可以选择保存图片,选择下一张图片或者上一张图片。

源代码:

[Python] 纯文本查看 复制代码
import cv2
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.widgets import Button, RadioButtons
import tkinter as tk
from tkinter import simpledialog, colorchooser, filedialog
import os
# 初始化数据
clicked_points_dict = {}  # 存储每个图像的标记点信息
color_mapping = {'Red': (1.0, 0.0, 0.0), 'Yellow': (1.0, 1.0, 0.0), 'Blue': (0.0, 0.0, 1.0), 'Green': (0.0, 1.0, 0.0)}
# 图像文件路径列表
image_paths = []
current_image_index = 0
image_rgb = None
# 创建 tkinter 窗口
root = tk.Tk()
root.title("Image Annotator")
# 创建 Figure 对象和 Axes 对象
fig, ax = plt.subplots()
ax.set_title("No Image Selected")
ax.set_xlabel("X")
ax.set_ylabel("Y")
# 将 Matplotlib 的 Figure 嵌入到 tkinter 窗口中
canvas = FigureCanvasTkAgg(fig, master=root)
canvas_widget = canvas.get_tk_widget()
canvas_widget.pack(fill=tk.BOTH, expand=True)
# 显示图片像素大小
pixel_text = ""
pixel_label = tk.Label(root, text=pixel_text)
pixel_label.pack(anchor='nw', padx=10, pady=10)
# 鼠标点击事件处理函数
def on_click(event):
    if event.button == 1:  # 左键点击
        x = int(event.xdata)
        y = int(event.ydata)
        color = point_colors.value_selected
        size = int(point_sizes.value_selected)
        clicked_points_dict[current_image_index].append((x, y, color, size))
        
        ax.clear()
        ax.imshow(image_rgb)
        
        for point in clicked_points_dict[current_image_index]:
            x, y, point_color, point_size = point
            color_rgb = color_mapping.get(point_color, (1.0, 0.0, 0.0))  # 默认红色
            ax.plot(x, y, 'ro', markersize=point_size, markerfacecolor=color_rgb)
            ax.annotate(f'({x}, {y})', (x, y), textcoords="offset points", xytext=(0,10), ha='center', fontsize=8, color=color_rgb)
        
        ax.set_title("Click on the image to select points")
        ax.set_xlabel("X")
        ax.set_ylabel("Y")
        canvas.draw()
# 载入图像
def load_image(path):
    global image_rgb, width, height, pixel_text
    image = cv2.imread(path)
    image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    height, width = image.shape[:2]
    pixel_text = f"Image Size: {width} x {height}"
    pixel_label.config(text=pixel_text)
   
    ax.clear()
    ax.imshow(image_rgb)
    ax.set_title("Click on the image to select points")
    ax.set_xlabel("X")
    ax.set_ylabel("Y")
    canvas.draw()
# 加载当前索引的图像
def load_current_image():
    global current_image_index
    if current_image_index < 0 or current_image_index >= len(image_paths):
        return
    image_path = image_paths[current_image_index]
    load_image(image_path)
# 加载上一张图像
def load_previous_image(event):
    global current_image_index
    current_image_index -= 1
    if current_image_index < 0:
        current_image_index = 0
    load_current_image()
# 加载下一张图像
def load_next_image(event):
    global current_image_index
    current_image_index += 1
    if current_image_index >= len(image_paths):
        current_image_index = len(image_paths) - 1
    load_current_image()
# 选择图像文件夹按钮点击事件处理函数
def choose_folder():
    global image_paths, current_image_index, clicked_points_dict
    folder_path = filedialog.askdirectory(title="Select Image Folder")
    if folder_path:
        image_paths = [os.path.join(folder_path, file) for file in sorted(os.listdir(folder_path)) if file.lower().endswith(('.jpg', '.jpeg', '.png', '.bmp'))]
        clicked_points_dict = {i: [] for i in range(len(image_paths))}
        current_image_index = 0
        load_current_image()
# 保存按钮点击事件处理函数
def save_image(event):
    global clicked_points_dict
    new_image = np.copy(image_rgb)
    for point in clicked_points_dict[current_image_index]:
        x, y, point_color, point_size = point
        color_rgb = color_mapping.get(point_color, (1.0, 0.0, 0.0))  # 默认红色
        cv2.circle(new_image, (x, y), point_size, (int(color_rgb[0]*255), int(color_rgb[1]*255), int(color_rgb[2]*255)), -1)  # 标记点为指定颜色
    save_path = filedialog.asksaveasfilename(defaultextension=".jpg", filetypes=[("JPEG files", "*.jpg")])
    if save_path:
        cv2.imwrite(save_path, cv2.cvtColor(new_image, cv2.COLOR_RGB2BGR))
        print(f"Image with marked points saved to {save_path}")
# 窗口大小变化事件处理函数
def on_resize(event):
    # 重新绘制图像以保持宽高比不变
    load_current_image()
# 创建点颜色选择菜单
color_choices = ['Red', 'Yellow', 'Blue', 'Green']
ax_color = plt.axes([0.08, 0.9, 0.3, 0.1], aspect='equal')
point_colors = RadioButtons(ax_color, color_choices)
# 创建点大小选择菜单
size_choices = ['5', '10', '15', '20']
ax_size = plt.axes([0.28, 0.9, 0.1, 0.1], aspect='equal')
point_sizes = RadioButtons(ax_size, size_choices)
# 创建保存按钮
ax_save = plt.axes([0.9, 0.01, 0.05, 0.04])
btn_save = Button(ax_save, 'Save')
btn_save.on_clicked(save_image)
# 创建选择图像文件夹按钮
ax_choose_folder = plt.axes([0.65, 0.9, 0.28, 0.04])
btn_choose_folder = Button(ax_choose_folder, 'Choose Image Folder')
btn_choose_folder.on_clicked(lambda x: choose_folder())
# 创建上一张图像按钮
ax_previous_image = plt.axes([0.5, 0.01, 0.20, 0.04])
btn_previous_image = Button(ax_previous_image, 'Previous Image')
btn_previous_image.on_clicked(load_previous_image)
# 创建下一张图像按钮
ax_next_image = plt.axes([0.7, 0.01, 0.20, 0.04])
btn_next_image = Button(ax_next_image, 'Next Image')
btn_next_image.on_clicked(load_next_image)
# 绑定鼠标点击事件处理函数
fig.canvas.mpl_connect('button_press_event', on_click)
# 绑定窗口大小变化事件处理函数
fig.canvas.mpl_connect('resize_event', on_resize)
# 启动 tkinter 主循环
tk.mainloop()


我也只是尝试写一下,有啥问题,希望大家一起解决!


标记

标记

标记前

标记前

标记后

标记后

免费评分

参与人数 1吾爱币 +7 热心值 +1 收起 理由
wushaominkk + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 19:43

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表