当前位置: 首页 > news >正文

2025-07-15通过边缘线检测图像里的主体有没有出血

本节观点:一个好的提问就已经解决了问题的90%。

对于问题的描述正确与否决定了解决问题的方法和路径,所以我们在AI时代必须要学会正确的描述问题和表达问题,否则即使有AI辅助也是很难精准的解决问题。

我的问题:

如何利用代码从图片集中筛选出出血的图片,定义出血:提取图片中的边缘,我希望通过设置一个值来界定,比如所有边缘线与图像边缘接触的总条数超过10条才算出血图片,另外图像中的边缘线段至少长20像素才计入有效边缘线段,同时要考虑图片路径含有中文的问题。

如下图所示,其中1,2是出血的图,3,4是没有出血的图。通过上方的描述提交给AI,AI就能帮我们实现批量筛选所有出血的图片。
在这里插入图片描述

特别说明:

国产AI水平确实远低于国外的,同样的问题,GPT一次就搞定了代码,而豆包,qwen,deepseek等从多国产AI提问了N轮最后连最基本的读图时中文路径问题都无法搞定,可笑至极。加油国产AI。

import cv2
import numpy as np
import os
import shutildef read_image_chinese_path(image_path):# 支持中文路径读取image_data = np.fromfile(image_path, dtype=np.uint8)img = cv2.imdecode(image_data, cv2.IMREAD_COLOR)return imgdef is_bleeding_image(image_path, edge_touch_threshold=10, min_edge_length=20):img = read_image_chinese_path(image_path)if img is None:print(f"无法读取图片: {image_path}")return Falseheight, width = img.shape[:2]# 灰度 + Canny 边缘检测gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)edges = cv2.Canny(gray, 100, 200)# 查找轮廓contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)edge_touch_count = 0for cnt in contours:# 计算轮廓长度length = cv2.arcLength(cnt, closed=False)if length < min_edge_length:continue  # 过滤掉短轮廓# 检查是否有点在图像边界for point in cnt:x, y = point[0]if x <= 0 or y <= 0 or x >= width-1 or y >= height-1:edge_touch_count += 1break  # 这条轮廓计数一次就够return edge_touch_count >= edge_touch_thresholddef find_and_move_bleeding_images(folder_path, output_folder, edge_touch_threshold=10, min_edge_length=20):if not os.path.exists(output_folder):os.makedirs(output_folder)for root, _, files in os.walk(folder_path):for file in files:if file.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp')):file_path = os.path.join(root, file)if is_bleeding_image(file_path, edge_touch_threshold, min_edge_length):print(f"检测到出血: {file_path}")# 生成输出路径output_path = os.path.join(output_folder, file)# 如果重名文件,改名避免覆盖base, ext = os.path.splitext(output_path)counter = 1while os.path.exists(output_path):output_path = f"{base}_{counter}{ext}"counter += 1# 移动文件shutil.move(file_path, output_path)if __name__ == "__main__":input_folder = r"images"         # 输入图片文件夹路径output_folder = r"output_images"    # 检测到出血后保存到这里find_and_move_bleeding_images(input_folder, output_folder,edge_touch_threshold=10,min_edge_length=20)print("✅ 所有出血图片已移动至 output_images 文件夹")

最后描述问题过程:
第1次:
我有几张图片,其中有一张图片内容是非常完整的,主体在图的中间(这里要考虑图片的背景,有的图片背景是纯白色,有的图片是纯黑色,有的图片的是其它纯色的背景),而其余的图片都是主体出血。如何利用代码检测或筛选出主体没𠕇出血的图片
出来的代码只能做到60%选对。

第2次:
重新整理一下思路:1,分别取出图像外边1像素宽的边缘,2.分别计算每边的像素色值是否一样,如果计算出有明显不同的像素色值部分的像素总计超过5%单边所有像素色值比例的说明是出血图像。
出来的代码只能做到65%选对。

第3次:
如何利用代码从图片集中筛选出出血的图片,定义出血:提取图片中的边缘,我希望通过设置一个值来界定,比如所有边缘线与图像边缘接触的总条数超过10条才算出血图片,另外图像中的边缘线段至少长20像素才计入有效边缘线段,同时要考虑图片路径含有中文的问题。
出来的代码只能做到95%选对。

最终代码

import cv2
import numpy as np
import os
import shutildef read_image_chinese_path(image_path):"""支持中文路径读取"""image_data = np.fromfile(image_path, dtype=np.uint8)img = cv2.imdecode(image_data, cv2.IMREAD_COLOR)return imgdef has_large_colored_block_with_edges(img, block_size=10, edge_proximity=5):"""检查是否存在大于 block_size 的色块且色块两侧有边缘线,并且色块接近图像边缘"""height, width = img.shape[:2]# 边缘检测gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)edges = cv2.Canny(gray, 100, 200)# 查找轮廓contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)for cnt in contours:x, y, w, h = cv2.boundingRect(cnt)# 判断色块尺寸是否足够大if w >= block_size and h >= block_size:# 检查色块是否靠近图像边缘if (x <= edge_proximity or y <= edge_proximity orx + w >= width - edge_proximity ory + h >= height - edge_proximity):# 检查 ROI 内边缘线roi_edges = edges[y:y+h, x:x+w]top_edge = np.sum(roi_edges[0, :] > 0)bottom_edge = np.sum(roi_edges[-1, :] > 0)left_edge = np.sum(roi_edges[:, 0] > 0)right_edge = np.sum(roi_edges[:, -1] > 0)edge_threshold = 3  # 至少3个像素视作边缘线if (left_edge >= edge_threshold and right_edge >= edge_threshold):return True  # 找到了符合要求的色块return Falsedef is_bleeding_image(image_path, edge_touch_threshold=10, min_edge_length=20, block_size=10):img = read_image_chinese_path(image_path)if img is None:print(f"无法读取图片: {image_path}")return Falseheight, width = img.shape[:2]# 灰度 + 边缘检测gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)edges = cv2.Canny(gray, 100, 200)# 查找所有外轮廓contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)edge_touch_count = 0for cnt in contours:# 计算轮廓长度length = cv2.arcLength(cnt, closed=False)if length < min_edge_length:continue# 检查是否触碰图像边界for point in cnt:x, y = point[0]if x <= 0 or y <= 0 or x >= width-1 or y >= height-1:edge_touch_count += 1break# 条件1:足够多的触边线条if edge_touch_count < edge_touch_threshold:return False# 条件2:是否有色块两侧有边缘if not has_large_colored_block_with_edges(img, block_size):return Falsereturn True  # 两个条件都满足def find_and_move_bleeding_images(folder_path, output_folder, edge_touch_threshold=10, min_edge_length=20, block_size=10):if not os.path.exists(output_folder):os.makedirs(output_folder)for root, _, files in os.walk(folder_path):for file in files:if file.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp')):file_path = os.path.join(root, file)if is_bleeding_image(file_path, edge_touch_threshold, min_edge_length, block_size):print(f"检测到出血: {file_path}")# 生成输出路径output_path = os.path.join(output_folder, file)base, ext = os.path.splitext(output_path)counter = 1while os.path.exists(output_path):output_path = f"{base}_{counter}{ext}"counter += 1# 移动文件shutil.move(file_path, output_path)if __name__ == "__main__":input_folder = r"images"         # 输入文件夹路径output_folder = r"output_images"    # 出血图片保存路径find_and_move_bleeding_images(input_folder, output_folder,edge_touch_threshold=1,    # 触边线条数阈值min_edge_length=2,         # 有效边缘线长度block_size=2               # 色块尺寸阈值)print("✅ 所有出血图片已移动至 output_images 文件夹")

在这里插入图片描述
在这里插入图片描述


文章转载自:
http://bender.riewr.cn
http://arteriotomy.riewr.cn
http://chlordane.riewr.cn
http://blooded.riewr.cn
http://biociation.riewr.cn
http://centaurae.riewr.cn
http://almirah.riewr.cn
http://certified.riewr.cn
http://alamo.riewr.cn
http://anopisthograph.riewr.cn
http://belike.riewr.cn
http://appetiser.riewr.cn
http://adieux.riewr.cn
http://aspartate.riewr.cn
http://atmospheric.riewr.cn
http://barycenter.riewr.cn
http://allantoic.riewr.cn
http://anethole.riewr.cn
http://audibly.riewr.cn
http://addend.riewr.cn
http://cairngorm.riewr.cn
http://bactericidal.riewr.cn
http://chewink.riewr.cn
http://breakable.riewr.cn
http://chow.riewr.cn
http://cardinality.riewr.cn
http://anticathode.riewr.cn
http://bessy.riewr.cn
http://accomplice.riewr.cn
http://amusing.riewr.cn
http://www.dtcms.com/a/281703.html

相关文章:

  • IMU 能为无人机提供什么数据?
  • 【论文阅读】A Survey on Knowledge-Oriented Retrieval-Augmented Generation(3)
  • 移动端字体适配
  • 谷歌浏览器控制台如何切换中文
  • StampedLock分析
  • 链表的 哑结点的本质
  • Python 程序设计讲义(1):PyCharm 安装教程
  • WebView JSBridge 无响应问题排查实录 全流程定位桥接调用失效
  • 深度学习·目标检测和语义分割基础
  • 77、【OS】【Nuttx】【启动】caller-saved 和 callee-saved 示例:栈指针和帧指针(上)
  • Qt图形视图框架5-状态机框架
  • Springboot儿童认知图文辅助系统6yhkv(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
  • 再见吧,Windows自带记事本,这个轻量级文本编辑器太香了
  • 基于mybatis的基础操作的思路
  • C++-linux系统编程 8.进程(二)exec函数族详解
  • 终端安全管理系统为什么需要使用,企业需要的桌面管理软件
  • X 射线探伤证考试核心:辐射安全基础知识点梳理
  • golang二级缓存示例
  • HC165并转串
  • js分支语句和循环语句
  • 如何写一份有效的技术简历?
  • vscode输出中文乱码问题的解决
  • QTableView鼠标双击先触发单击信号
  • Vue 常用的 ESLint 规则集
  • resources为什么是类的根目录
  • Linux 基本操作与服务器部署
  • 【高等数学】第三章 微分中值定理与导数的应用——第一节 不定积分的概念与性质
  • Android 图片压缩
  • 21.映射字典的值
  • 【强化学习】Reinforcement Learning基础概述