圖像處理:預覽并繪制圖像細節

前言

因為最近在搞畢業論文的事情,要做出一下圖像細節對比圖,所以我這里寫了兩個腳本,一個用于框選并同時預覽圖像放大細節,可顯示并返回框選圖像的坐標,另外一個是輸入框選圖像的坐標并將放大的細節放置在圖像中,效果如下所示:

效果也是相當不錯的,好了咱們也不必多說,就是教會大家怎么使用這兩個腳本就可以了。?

框選圖像并預覽放大細節

我們這里寫了一個圖像區域的選擇工具,主要是選擇好圖像路徑,框選和文字的顏色,以及放大的倍數,此處放大的倍數僅用于查看,所以不用擔心最后的效果。

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.pswp.cn/pingmian/81076.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/81076.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/81076.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

基于javaweb的SSM駕校管理系統設計與實現(源碼+文檔+部署講解)

技術范圍&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬蟲、數據可視化、小程序、安卓app、大數據、物聯網、機器學習等設計與開發。 主要內容&#xff1a;免費功能設計、開題報告、任務書、中期檢查PPT、系統功能實現、代碼編寫、論文編寫和輔導、論文…

限制 MySQL 服務只能被內網 `192.168.1.*` 網段的設備訪問

1. 修改 MySQL 配置文件 MySQL 默認監聽所有網絡接口(0.0.0.0),需要將其綁定到內網 IP 地址或限制訪問范圍。 (1)編輯 MySQL 配置文件 找到 MySQL 的主配置文件,通常是 /etc/my.cnf 或 /etc/mysql/my.cnf。使用文本編輯器打開: sudo vi /etc/my.cnf(2)設置 bind-a…

uniapp-商城-55-后臺 新增商品(分類、驗證和彈窗屬性)

1、概述 在前面 &#xff0c;我們將商品頁面的布局給完成了&#xff0c;這里來對表單的標簽輸入進行校驗&#xff0c;看看這里的校驗還是不是也需要兼容微信小程序&#xff0c;還有沒有前面遇到的自定義正則進行校驗的情況。 另外這里還需要完成商品屬性的添加&#xff0c;就是…

PyInstaller 打包后 Excel 轉 CSV 報錯解決方案:“excel file format cannot be determined“

一、問題背景 在使用 Python 開發 Excel 轉 CSV 工具時,直接運行腳本(python script.py)可以正常工作,但通過 PyInstaller 打包成可執行文件后,出現以下報錯: excel file format cannot be determined, you must specify an engine manually 該問題通常發生在使用pandas…

【HTML 全棧進階】從語義化到現代 Web 開發實戰

目錄 &#x1f31f; 前言&#x1f3d7;? 技術背景與價值&#x1fa79; 當前技術痛點&#x1f6e0;? 解決方案概述&#x1f465; 目標讀者說明 &#x1f9e0; 一、技術原理剖析&#x1f4ca; 核心概念圖解&#x1f4a1; 核心作用講解&#x1f527; 關鍵技術模塊說明?? 技術選…

小結:網頁性能優化

網頁性能優化是提升用戶體驗、減少加載時間和提高資源利用率的關鍵。以下是針對網頁生命周期和事件處理的性能優化技巧&#xff0c;結合代碼示例&#xff0c;重點覆蓋加載、渲染、事件處理和資源管理等方面。 1. 優化加載階段 減少關鍵資源請求&#xff1a; 合并CSS/JS文件&a…

【AI學習】AI大模型技術發展研究月報的生成提示詞

AI大模型技術發展研究月報生成提示詞 請輸出AI大模型技術發展研究月報&#xff0c;要求如下&#xff1a; —————————— 任務目標 在今天&#xff08;{{today}}&#xff09;往前連續 30 天內&#xff0c;檢索已正式公開發表的、與AI大模型&#xff08;參數量 ≥10B&am…

AI 實踐探索:輔助生成測試用例

背景 目前我們的測試用例主要依賴人工生成和維護&#xff0c;AI時代的來臨&#xff0c;我們也在思考“AI如何賦能業務”&#xff0c;提出了如下命題&#xff1a; “探索通過AI輔助生成測試用例&#xff0c;完成從需求到測試用例生成的穿刺”。 目標 找全測試路徑輔助生成測…

C#實現訪問遠程硬盤(附源碼)

在現實場景中&#xff0c;我們經常用到遠程桌面功能&#xff0c;而在某些場景下&#xff0c;我們需要使用類似的遠程硬盤功能&#xff0c;這樣能非常方便地操作對方電腦磁盤的目錄、以及傳送文件。那么&#xff0c;這樣的遠程硬盤功能要怎么實現了&#xff1f; 這次我們將給出…

02.Golang 切片(slice)源碼分析(一、定義與基礎操作實現)

Golang 切片&#xff08;slice&#xff09;源碼分析&#xff08;一、定義與基礎操作實現&#xff09; 注意當前go版本代碼為1.23 一、定義 slice 的底層數據是數組&#xff0c;slice 是對數組的封裝&#xff0c;它描述一個數組的片段。兩者都可以通過下標來訪問單個元素。 數…

記參加一次數學建模

題目請到全國大學生數學建模競賽下載查看。 注&#xff1a;過程更新了很多文件&#xff0c;所有這里貼上的有些內容不是最新的&#xff08;而是草稿&#xff09;。 注&#xff1a;我們隊伍并沒有獲獎&#xff0c;文章內容僅供一樂。 從這次比賽&#xff0c;給出以下賽前建議 …

virtualbox虛擬機中的ubuntu 20.04.6安裝新的linux內核5.4.293 | 并增加一個系統調用 | 證書問題如何解決

參考文章&#xff1a;linux添加系統調用【簡單易懂】【含32位系統】【含64位系統】_64位 32位 系統調用-CSDN博客 安裝新內核 1. 在火狐下載你需要的版本的linux內核壓縮包 這里我因為在windows上面下載過&#xff0c;配置過共享文件夾&#xff0c;所以直接復制粘貼通過共享文…

[Java實戰]Spring Boot 3 整合 Ehcache 3(十九)

[Java實戰]Spring Boot 3 整合 Ehcache 3&#xff08;十九&#xff09; 引言 在微服務和高并發場景下&#xff0c;緩存是提升系統性能的關鍵技術之一。Ehcache 作為 Java 生態中成熟的內存緩存框架&#xff0c;其 3.x 版本在性能、功能和易用性上均有顯著提升。本文將詳細介紹…

LlamaIndex 第九篇 Indexing索引

索引概述 數據加載完成后&#xff0c;您將獲得一個文檔對象(Document)列表&#xff08;或節點(Node)列表&#xff09;。接下來需要為這些對象構建索引(Index)&#xff0c;以便開始執行查詢。 索引&#xff08;Index&#xff09; 是一種數據結構&#xff0c;能夠讓我們快速檢索…

【問題排查】easyexcel日志打印Empty row!

問題原因 日志打印??I/O 操作開銷?&#xff08;如 Log4j 的 FileAppender&#xff09;會阻塞業務線程&#xff0c;直到日志寫入完成&#xff0c;導致接口響應變慢 問題描述 在線上環境&#xff0c;客戶反饋導入一個不到1MB的excel文件&#xff0c;耗時將近5分鐘。 問題排…

代碼隨想錄第51天|島嶼數量(深搜)、島嶼數量(廣搜)、島嶼的最大面積

1.島嶼數量&#xff08;深搜&#xff09; ---》模板題 版本一寫法&#xff1a;下一個節點是否能合法已經判斷完了&#xff0c;傳進dfs函數的就是合法節點。 #include <iostream> #include <vector> using namespace std;int dir[4][2] {0, 1, 1, 0, -1, 0, 0, -…

Made with Unity | 從影視到游戲:《魷魚游戲》IP 的邊界拓展

優質IP的跨媒體開發潛力不可限量。以現象級劇集《魷魚游戲》為例&#xff0c;Netflix旗下游戲工作室Boss Fight在第二季開播前夕推出的手游《Squid Game: Unleashed》&#xff0c;一經發布便橫掃全球107個國家和地區的App Store免費游戲榜首。 這款多人派對大逃殺游戲完美還原…

allure 報告更改標題和語言為中文

在網上看到好多談到更改allure 的標題設置都很麻煩&#xff0c;去更改JSON文件 其實可以有更簡單的辦法&#xff0c;就是在生成報表時增加參數 使用allure --help 查看&#xff1a; --lang, --report-language 設置報告的語言&#xff0c;默認是應用 The report language. …

HGDB索引膨脹的檢查與處理思路

文章目錄 環境文檔用途詳細信息 環境 系統平臺&#xff1a;Linux x86-64 Red Hat Enterprise Linux 7 版本&#xff1a;4.5.8 文檔用途 本文檔主要介紹HGDB索引膨脹的定義、產生的原因、如何檢查以及遇到索引膨脹如何處理&#xff08;包括預防和解決&#xff09; 詳細信息 …

【Python CGI編程】

Python CGI&#xff08;通用網關接口&#xff09;編程是早期Web開發中實現動態網頁的技術方案。以下是系統化指南&#xff0c;包含核心概念、實現步驟及安全實踐&#xff1a; 一、CGI 基礎概念 1. 工作原理 瀏覽器請求 → Web服務器&#xff08;如Apache&#xff09; → 執行…