图像处理:预览并绘制图像细节

前言

因为最近在搞毕业论文的事情,要做出一下图像细节对比图,所以我这里写了两个脚本,一个用于框选并同时预览图像放大细节,可显示并返回框选图像的坐标,另外一个是输入框选图像的坐标并将放大的细节放置在图像中,效果如下所示:

效果也是相当不错的,好了咱们也不必多说,就是教会大家怎么使用这两个脚本就可以了。 

框选图像并预览放大细节

我们这里写了一个图像区域的选择工具,主要是选择好图像路径,框选和文字的颜色,以及放大的倍数,此处放大的倍数仅用于查看,所以不用担心最后的效果。

import cv2def select_roi_region(image_path, line_color=(0, 255, 0), zoom_factor=3):drawing = Falseix, iy = -1, -1x, y, w, h = 0, 0, 0, 0img = cv2.imread(image_path)clone = img.copy()# 鼠标回调函数def mouse_callback(event, cur_x, cur_y, flags, param):nonlocal ix, iy, drawing, x, y, w, hif event == cv2.EVENT_LBUTTONDOWN:drawing = Trueix, iy = cur_x, cur_yx, y, w, h = 0, 0, 0, 0elif event == cv2.EVENT_MOUSEMOVE and drawing:temp_img = clone.copy()cv2.rectangle(temp_img, (ix, iy), (cur_x, cur_y), line_color, 2)x1, y1 = min(ix, cur_x), min(iy, cur_y)x2, y2 = max(ix, cur_x), max(iy, cur_y)if x2 > x1 and y2 > y1:try:roi = img[y1:y2, x1:x2]if roi.size > 0:enlarged = cv2.resize(roi, None, fx=3, fy=3,interpolation=cv2.INTER_CUBIC)cv2.imshow("Enlarged Preview", enlarged)except Exception as e:passcur_w = abs(cur_x - ix)cur_h = abs(cur_y - iy)if cur_w > 0 and cur_h > 0:try:roi = img[y1:y2, x1:x2]enlarged = cv2.resize(roi, None, fx=zoom_factor, fy=zoom_factor,interpolation=cv2.INTER_CUBIC)cv2.imshow("Enlarged Preview", enlarged)except:passcv2.putText(temp_img, f"X:{x1} Y:{y1} W:{cur_w} H:{cur_h}",(10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, line_color, 2)cv2.imshow("Select ROI (SPACE=Clear | ENTER=Confirm)", temp_img)elif event == cv2.EVENT_LBUTTONUP:drawing = Falsex = min(ix, cur_x)y = min(iy, cur_y)w = abs(cur_x - ix)h = abs(cur_y - iy)cv2.rectangle(clone, (x, y), (x + w, y + h), line_color, 2)cv2.putText(clone, f"X:{x} Y:{y} W:{w} H:{h}", (10, 30),cv2.FONT_HERSHEY_SIMPLEX, 0.7, line_color, 2)cv2.imshow("Select ROI (SPACE=Clear | ENTER=Confirm)", clone)cv2.namedWindow("Select ROI (SPACE=Clear | ENTER=Confirm)")cv2.setMouseCallback("Select ROI (SPACE=Clear | ENTER=Confirm)", mouse_callback)while True:cv2.imshow("Select ROI (SPACE=Clear | ENTER=Confirm)", clone)key = cv2.waitKey(1) & 0xFF# 空格键:清除选择if key == 32:clone = img.copy()ix, iy = -1, -1x, y, w, h = 0, 0, 0, 0try:cv2.destroyWindow("Enlarged Preview") if cv2.getWindowProperty("Enlarged Preview", 0) >=0 else Noneexcept:passcv2.imshow("Select ROI (SPACE=Clear | ENTER=Confirm)", clone)# 回车键:确认选择if key == 13:try:cv2.destroyWindow("Enlarged Preview")except:passbreakcv2.destroyAllWindows()print(f"Final selection - X:{x} Y:{y} W:{w} H:{h}")return (x, y, w, h)if __name__=="__main__":select_roi_region(r'E:\PythonProject\img_processing_techniques_main\Enlarge_local_details\images\781.png'
)

下面是我们的这个使用效果:

有一点问题就是在绘制好图像后再选框就会将文字遮挡住:

但是我们是提供了清楚键的,你只需要按下空格键就可以将全图的文字和框清理掉了,最后选择好合适的区域后,按下Enter键确定你框选的区域,以便进行下一步操作。

这里返回的坐标是(x,y,w,h),这种方式便于我们控制起始点和框的大小。

框选图像并放置放大细节

这里需要的是选择图像路径,框选的坐标,也提供放置位置的坐标,放大的系数,线条的颜色,宽度,以及是否绘制箭头。

如果你不提供放置的位置也可以,我们提供了一种自动计算位置的方法,主要就是比较框选区域的位置,然后计算出其对角线位置返回坐标。

import math
from PIL import Image, ImageDraw, ImageTkdef plot_highlight_region(image_path, region_to_zoom, paste_position=None, zoom_factor=3,line_color="red", line_wide=2, show_arrow=True, arrow_size=5):x, y, w, h = region_to_zoomimg = Image.open(image_path).convert("RGB")img_w, img_h = img.sizeoriginal_copy = img.copy()zoomed_w = int(w * zoom_factor)zoomed_h = int(h * zoom_factor)cropped = original_copy.crop((x, y, x + w, y + h))zoomed = cropped.resize((zoomed_w, zoomed_h), Image.Resampling.LANCZOS)if paste_position is None:if x + w < img_w / 2:paste_x = img_w - zoomed_welse:paste_x = 0if y + h < img_h / 2:paste_y = img_h - zoomed_helse:paste_y = 0paste_x = max(0, min(paste_x, img_w - zoomed_w))paste_y = max(0, min(paste_y, img_h - zoomed_h))paste_position = (paste_x, paste_y)img.paste(zoomed, paste_position)draw = ImageDraw.Draw(img)draw.rectangle([(x, y), (x + w, y + h)],outline=line_color,width=line_wide)paste_x, paste_y = paste_positiondraw.rectangle([paste_position,(paste_x + zoomed_w, paste_y + zoomed_h)],outline=line_color, width=line_wide)if show_arrow:def get_side_center(rect, side):x, y, w, h = rectreturn {'left': (x, y + h // 2),'right': (x + w, y + h // 2),'top': (x + w // 2, y),'bottom': (x + w // 2, y + h)}[side]src_rect = (x, y, w, h)dst_rect = (paste_position[0], paste_position[1], zoomed_w, zoomed_h)dx = (dst_rect[0] + zoomed_w / 2) - (x + w / 2)dy = (dst_rect[1] + zoomed_h / 2) - (y + h / 2)if abs(dx) > abs(dy):src_side = 'right' if dx > 0 else 'left'dst_side = 'left' if dx > 0 else 'right'else:src_side = 'bottom' if dy > 0 else 'top'dst_side = 'top' if dy > 0 else 'bottom'start_point = get_side_center(src_rect, src_side)end_point = get_side_center(dst_rect, dst_side)draw.line([start_point, end_point], fill=line_color, width=line_wide)arrow_size = line_wide * arrow_sizeangle = math.atan2(end_point[1] - start_point[1], end_point[0] - start_point[0])p1 = (end_point[0] - arrow_size * math.cos(angle - math.pi / 6),end_point[1] - arrow_size * math.sin(angle - math.pi / 6))p2 = (end_point[0] - arrow_size * math.cos(angle + math.pi / 6),end_point[1] - arrow_size * math.sin(angle + math.pi / 6))draw.polygon([end_point, p1, p2], fill=line_color)return imgif __name__ == "__main__":# 定义要放大的区域 (x, y, width, height)region_to_zoom = (256, 250, 50, 70)im_path = r'E:\PythonProject\img_processing_techniques_main\Enlarge_local_details\gtimage\781.png'im = plot_highlight_region(im_path, region_to_zoom)im.save("output.png")

我们先来看看,提供了放置坐标的效果:

if __name__ == "__main__":# 定义要放大的区域 (x, y, width, height)region_to_zoom = (256, 250, 50, 70)im_path = r'E:\PythonProject\img_processing_techniques_main\Enlarge_local_details\gtimage\861.png'im = plot_highlight_region(im_path, region_to_zoom, (22, 22))im.save("output.png")

自动计算的效果:

if __name__ == "__main__":# 定义要放大的区域 (x, y, width, height)region_to_zoom = (22, 22, 50, 70)im_path = r'E:\PythonProject\img_processing_techniques_main\Enlarge_local_details\gtimage\861.png'im = plot_highlight_region(im_path, region_to_zoom)im.save("output.png")

当然这里的自动计算还只是四个角。目前来说也算足够了。

关闭箭头的效果:

if __name__ == "__main__":# 定义要放大的区域 (x, y, width, height)region_to_zoom = (300, 250, 50, 70)im_path = r'E:\PythonProject\img_processing_techniques_main\Enlarge_local_details\gtimage\861.png'im = plot_highlight_region(im_path, region_to_zoom, show_arrow=False)im.save("output.png")

总结

如果只需要画框那么直接用下面的简略版本即可:

def highlight_region(image_path, region_to_zoom, line_color="red", line_wide=2):x, y, w, h = region_to_zoomimg = Image.open(image_path).convert("RGB")img_copy = img.copy()draw = ImageDraw.Draw(img)draw.rectangle([(x, y), (x + w, y + h)],outline=line_color,width=line_wide)return img

我们将前面的两个脚本组合在一起,便于我们更好的观察

if __name__ == "__main__":# 定义要放大的区域 (x, y, width, height)from mouse import select_roi_regionim_path = r'E:\PythonProject\img_processing_techniques_main\Enlarge_local_details\gtimage\861.png'region_to_zoom = select_roi_region(im_path)im = plot_highlight_region(im_path, region_to_zoom, show_arrow=False)im.save("output.png")

这里会先运行预选框程序,等按下Enter键之后会直接返回坐标。

我们的图像就生成好了:

写完这篇我还得继续去画图了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/49417.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机指令分类和具体的表示的方式

1.关于计算机的指令系统 下面的这个就是我们的一个简单的计算机里面涉及到的指令&#xff1a; m就是我们的存储器里面的地址&#xff0c;可以理解为memory这个意思&#xff0c;r可以理解为rom这样的单词的首字母&#xff0c;帮助我们去进行这个相关的指令的记忆&#xff0c;不…

使用 OpenCV 将图像中标记特定颜色区域

在计算机视觉任务中&#xff0c;颜色替换是一种常见的图像处理操作&#xff0c;广泛用于视觉增强、目标高亮、伪彩色渲染等场景。本文介绍一种简单而高效的方式&#xff0c;基于 OpenCV 检测图像中接近某种颜色的区域&#xff0c;并将其替换为反色&#xff08;对比色&#xff0…

会议分享|高超声速流动测量技术研讨会精彩探析

由中国空气动力学会测控专业委员会主办&#xff0c;中国科学技术大学工程科学学院承办的第八届三次委员会暨高超声速流动测量技术研讨会&#xff0c;5月16日在合肥盛大开幕。 会议专家报告分享了高超声速流动测量的最新研究成果、挑战与突破&#xff0c;展示了PIV高速摄像机、粒…

代码随想录算法训练营第三十八天打卡

今天是动态规划的第三天&#xff0c;昨天的不同路径与整数分解的几道题目大家理解得如何&#xff1f;如果有疑问大家还是多去想想dp数组究竟是什么含义&#xff0c;还有我的状态转移是否正确&#xff0c;初始化是否正确&#xff0c;这一点很重要&#xff0c;今天的题目依旧是跑…

【全解析】EN18031标准下的SUM安全更新机制

在网络安全问题层出不穷的今天&#xff0c;无线电设备的安全更新是保障其正常运行、抵御威胁的核心环节。EN18031标准中的SUM&#xff08;Secure Update Mechanism&#xff09;安全更新机制&#xff0c;为无线电设备的软件更新安全筑牢了规范防线。接下来&#xff0c;让我们详细…

小学数学题批量生成及检查工具

软件介绍 今天给大家介绍一款近期发现的小工具&#xff0c;它非常实用。 软件特点与出题功能 这款软件体积小巧&#xff0c;不足两兆&#xff0c;具备强大的功能&#xff0c;能够轻松实现批量出题。使用时&#xff0c;只需打开软件&#xff0c;输入最大数和最小数&#xff0c…

【LeetCode 热题 100】动态规划 系列

&#x1f4c1; 70. 爬楼梯 状态标识&#xff1a;爬到第i层楼梯时&#xff0c;有多少种方法。 状态转移方程&#xff1a;dp[i] dp[i-1] dp[i-2]&#xff0c;表示从走一步和走两步的方式。 初始化&#xff1a;dp[1] 1 , dp[2] 2。 返回值&#xff1a;dp[n]&#xff0c;即走到…

Linux系统篇——文件描述符FD

&#x1f9e0; Linux 文件描述符&#xff08;File Descriptor&#xff09;详解与学习指南 一、什么是文件描述符&#xff08;fd&#xff09; 在 Linux 中&#xff0c;一切皆文件&#xff08;everything is a file&#xff09;&#xff0c;包括普通文件、目录、套接字&#xff…

CSS- 2.1 实战之图文混排、表格、表单、学校官网一级导航栏

本系列可作为前端学习系列的笔记&#xff0c;代码的运行环境是在HBuilder中&#xff0c;小编会将代码复制下来&#xff0c;大家复制下来就可以练习了&#xff0c;方便大家学习。 HTML系列文章 已经收录在前端专栏&#xff0c;有需要的宝宝们可以点击前端专栏查看&#xff01; 系…

文件同步2

请大家思考如何使用scp命令去解决这个问题。 有两种思路&#xff1a; 第一种&#xff1a;三个文件一个一个去拷贝。缺点是操作麻烦&#xff0c;要逐一操作。 第二种&#xff1a;重新把A上的conf拷贝到B上。缺点是会重复拷贝文件1&#xff0c;2&#xff0c;3&#xff0c;4。 …

Maven使用详解:Maven的概述(二)

一、核心定义与功能 Maven是由Apache软件基金会开发的开源项目管理工具&#xff0c;专为Java项目设计&#xff0c;主要用于自动化构建、依赖管理和项目标准化。其核心功能包括&#xff1a; 依赖管理&#xff1a;通过pom.xml文件声明依赖库&#xff0c;自动从中央仓库下载并管…

大疆无人机自主飞行解决方案局限性及增强解决方案-AIBOX:特色行业无人机巡检解决方案

大疆无人机自主飞行解决方案局限性及增强解决方案-AIBOX&#xff1a;特色行业无人机巡检解决方案 大疆无人机是低空行业无人机最具性价比的产品&#xff0c;尤其是大疆机场3的推出&#xff0c;以及持续自身产品升级迭代&#xff0c;包括司空2、大疆智图以及大疆智运等专业软件和…

leetcode:58. 最后一个单词的长度(python3解法)

难度&#xff1a;简单 给你一个字符串 s&#xff0c;由若干单词组成&#xff0c;单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度。 单词 是指仅由字母组成、不包含任何空格字符的最大子字符串。 示例 1&#xff1a; 输入&#xff1a;s "Hello World"…

Ubuntu24.04 安装 5080显卡驱动以及cuda

前言 之前使用Ubuntu22.04版本一直报错,然后换了24.04版本才能正常安装 一. 配置基础环境 Linux系统进行环境开发环境配置-CSDN博客 二. 安装显卡驱动 1.安装驱动 按以下步骤来&#xff1a; sudo apt update && sudo apt upgrade -y#下载最新内核并安装 sudo add…

Github 2025-05-15 Go开源项目日报 Top10

根据Github Trendings的统计,今日(2025-05-15统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Go项目10Python项目1Ollama: 本地大型语言模型设置与运行 创建周期:248 天开发语言:Go协议类型:MIT LicenseStar数量:42421 个Fork数量:27…

操作系统-锁/内存/中断/IO

文章目录 锁自旋锁互斥锁悲观锁和乐观锁 内存管理物理/虚拟内存页表段表虚拟内存布局写时复制copy on writebrk&#xff0c;mmap页面置换算法 中断中断分类中断流程 网络I/OI/O模型服务器处理并发请求 锁 自旋锁 自旋锁是一种基于忙等待&#xff08;Busy-Waiting&#xff09;…

校园一卡通安全策略研究调研报告

目录 一、研究背景 二、问题分析 三、解决方案 1.系统功能整合 2.用户体验优化 3.安全性能提升 4.代码说明 ①ConfigController.java ②FileController.java ③SushedianfeiController.java ④UserService.java ⑤XiaoyuankachongzhiController.java ⑥其他代码 …

EWOMAIL

1、错误 Problem: problem with installed package selinux-policy-targeted-3.14.3-41.el8.noarch package fail2ban-server-1.0.2-3.el8.noarch requires (fail2ban-selinux if selinux-policy-targeted), but none of the providers can be installed - package fail2ban-…

强化学习算法实战:一个例子实现sarsa、dqn、ddqn、qac、a2c、trpo、ppo

简介 在学习强化学习算法&#xff1a;sarsa、dqn、ddqn、qac、a2c、trpo、ppo时&#xff0c;由于有大量数据公式的推导&#xff0c;觉得十分晦涩&#xff0c;且听过就忘记了。 但是当把算法应用于实战时&#xff0c;代码的实现要比数据推导要直观很多。 接下来通过不同的算法实…

《数据库原理》部分习题解析1

《数据库原理》部分习题解析1 1. 名词解释 &#xff08;1&#xff09;关系&#xff08;2&#xff09;属性&#xff08;3&#xff09;域&#xff08;4&#xff09;元组&#xff08;5&#xff09;码&#xff08;6&#xff09;分量&#xff08;7&#xff09;关系模式 &#xff0…