生成两张找不同的图片,仅有一处差异,并且这个差异要不明显且复杂,使得寻找难度增加。

生成两张找不同的图片,仅有一处差异,并且这个差异要不明显且复杂,使得寻找难度增加。

为此,我们需要调整之前的代码,使得差异更为隐蔽。之前的代码中,我们直接在第二张图片中添加了一个红色多边形,可能过于显眼。

改进思路

  1. 差异的隐蔽性

    • 颜色相近:将差异部分的颜色设置为与背景或周围图形颜色相近,避免过于明显。
    • 形状变化:对某个已有的复杂形状进行微小的修改,而不是新增一个形状。
    • 位置微调:稍微移动某个形状的位置,使其与原图略有不同。
  2. 复杂性

    • 增加背景复杂度:绘制更多的随机图形,增加背景的复杂程度。
    • 使用复杂的图案:绘制包含细节的图形,如带有纹理的多边形。

实现方案

  • 选择一个随机的形状进行修改:在绘制图形时,记录所有绘制的图形参数(如形状类型、位置、大小、颜色等),然后随机选择其中一个,对其进行微小的修改,生成差异。

  • 差异的类型

    • 颜色变化:将选定形状的颜色稍微调整,使其与原颜色接近,但有细微差别。

    • 形状变化:改变形状的大小、角度,或者对多边形的某个顶点进行微调。

  • 确保差异不明显:差异的修改应在视觉上不易察觉,需要仔细观察才能发现。

修改后的代码

以下是修改后的完整代码,包含详细注释:

from PIL import Image, ImageDraw
import random# 设置图片尺寸
width, height = 800, 600# 创建空白图片
image1 = Image.new('RGB', (width, height), 'white')
image2 = image1.copy()# 创建绘图对象
draw1 = ImageDraw.Draw(image1)
draw2 = ImageDraw.Draw(image2)# 随机种子,保证每次生成的图形相同(可选)
random.seed(42)# 用于记录所有绘制的形状信息
shapes = []# 绘制复杂的图形和形状
for _ in range(300):# 随机选择形状类型shape_type = random.choice(['rectangle', 'ellipse', 'polygon', 'line'])# 随机颜色color = tuple(random.choices(range(256), k=3))# 随机位置和大小x1, y1 = random.randint(0, width), random.randint(0, height)x2, y2 = random.randint(0, width), random.randint(0, height)# 保证坐标顺序正确x0, x1 = min(x1, x2), max(x1, x2)y0, y1 = min(y1, y2), max(y1, y2)bbox = [x0, y0, x1, y1]# 随机多边形顶点num_points = random.randint(3, 8)points = [(random.randint(0, width), random.randint(0, height)) for _ in range(num_points)]# 线条宽度line_width = random.randint(1, 5)# 绘制形状并记录shape_info = {'type': shape_type, 'color': color, 'bbox': bbox, 'points': points, 'line_width': line_width}if shape_type == 'rectangle':draw1.rectangle(bbox, fill=color)draw2.rectangle(bbox, fill=color)elif shape_type == 'ellipse':draw1.ellipse(bbox, fill=color)draw2.ellipse(bbox, fill=color)elif shape_type == 'polygon':draw1.polygon(points, fill=color)draw2.polygon(points, fill=color)elif shape_type == 'line':draw1.line([x0, y0, x1, y1], fill=color, width=line_width)draw2.line([x0, y0, x1, y1], fill=color, width=line_width)# 记录形状信息shapes.append(shape_info)# 在 shapes 中随机选择一个形状进行微小的修改,作为差异
diff_shape = random.choice(shapes)# 在第二张图片上对该形状进行微小的修改
if diff_shape['type'] == 'rectangle' or diff_shape['type'] == 'ellipse':# 微调颜色new_color = tuple((c + random.randint(-30, 30)) % 256 for c in diff_shape['color'])# 在 image2 上重新绘制该形状,使用新的颜色if diff_shape['type'] == 'rectangle':draw2.rectangle(diff_shape['bbox'], fill=new_color)elif diff_shape['type'] == 'ellipse':draw2.ellipse(diff_shape['bbox'], fill=new_color)
elif diff_shape['type'] == 'polygon':# 微调一个顶点的位置idx = random.randint(0, len(diff_shape['points']) - 1)original_point = diff_shape['points'][idx]new_point = (original_point[0] + random.randint(-15, 15), original_point[1] + random.randint(-15, 15))new_points = diff_shape['points'].copy()new_points[idx] = new_point# 在 image2 上重新绘制该多边形,使用新的顶点draw2.polygon(new_points, fill=diff_shape['color'])
elif diff_shape['type'] == 'line':# 微调线条的终点x0, y0, x1, y1 = diff_shape['bbox']x1_new = x1 + random.randint(-15, 15)y1_new = y1 + random.randint(-15, 15)draw2.line([x0, y0, x1_new, y1_new], fill=diff_shape['color'], width=diff_shape['line_width'])# 保存图片
image1.save('find_difference_image1.png')
image2.save('find_difference_image2.png')print("两张找不同的图片已生成:find_difference_image1.png 和 find_difference_image2.png")
print("提示:两张图片仅有一处细微差异,快来找找看吧!")

代码详解

  1. 记录绘制的形状信息

    • 使用列表shapes保存每个绘制的形状的信息,包括类型、颜色、位置等。
    shapes = []
    
  2. 在绘制形状时,保存形状信息

    • 每次绘制形状后,将相关信息保存到shapes列表中。
    shape_info = {'type': shape_type, 'color': color, 'bbox': bbox, 'points': points, 'line_width': line_width}
    # ...
    shapes.append(shape_info)
    
  3. 随机选择一个形状进行微调

    • shapes列表中随机选择一个形状,作为差异的目标。
    diff_shape = random.choice(shapes)
    
  4. 根据形状类型进行微调

    • 矩形和椭圆:微调颜色,使其与原颜色接近但略有不同。

      new_color = tuple((c + random.randint(-30, 30)) % 256 for c in diff_shape['color'])
      # 重新绘制该形状,使用新的颜色
      
    • 多边形:微调一个顶点的位置。

      idx = random.randint(0, len(diff_shape['points']) - 1)
      original_point = diff_shape['points'][idx]
      new_point = (original_point[0] + random.randint(-15, 15), original_point[1] + random.randint(-15, 15))
      new_points = diff_shape['points'].copy()
      new_points[idx] = new_point
      # 重新绘制该多边形,使用新的顶点
      
    • 线条:微调线条的终点位置。

      x0, y0, x1, y1 = diff_shape['bbox']
      x1_new = x1 + random.randint(-15, 15)
      y1_new = y1 + random.randint(-15, 15)
      draw2.line([x0, y0, x1_new, y1_new], fill=diff_shape['color'], width=diff_shape['line_width'])
      
  5. 在第二张图片上应用微调

    • 使用draw2image2上重新绘制被修改的形状。
  6. 保存和提示

    • 保存两张图片,并提示用户有一处细微差异。

运行结果

执行代码后,您将获得两张图片:

  • find_difference_image1.png:原始图片。
  • find_difference_image2.png:仅有一处细微差异的图片。

提示:差异可能是某个形状的颜色略有不同,或某个多边形的顶点位置有细微变化,需要仔细观察才能发现。

调整参数以增加难度

  • 微调幅度

    • 颜色变化范围:random.randint(-30, 30),可以调整为更小的范围,如(-15, 15),使差异更不明显。

    • 位置变化范围:random.randint(-15, 15),可以减小范围,使形状的变化更细微。

  • 增加图形数量

    • range(300)中的数字增加,如range(500),使背景更加复杂。
  • 形状复杂度

    • 增加多边形的顶点数量,使形状更复杂。

      num_points = random.randint(5, 10)
      

注意事项

  • 随机性

    • 为了保证每次生成的图片一致,便于调试,我们设置了随机种子random.seed(42)

    • 如果希望每次生成不同的图片,可以移除或更改随机种子。

  • 依赖库

    • 请确保已安装Pillow库:

      pip install Pillow
      
  • 可能的差异类型

    • 颜色变化:颜色的RGB值变化范围在(-30, 30)内,视觉上不易察觉。

    • 位置变化:形状的位置微调在(-15, 15)像素内,变化较小。

验证差异

  • 人工查找

    • 打开两张图片,仔细对比,尝试找出差异所在。
  • 使用差异检测算法

    • 可以使用之前提供的差异检测代码,检测并标记出差异区域。

示例:使用差异检测算法

import cv2
import numpy as np# 读取两张图片
img1_color = cv2.imread('find_difference_image1.png')
img2_color = cv2.imread('find_difference_image2.png')# 转换为灰度图
img1_gray = cv2.cvtColor(img1_color, cv2.COLOR_BGR2GRAY)
img2_gray = cv2.cvtColor(img2_color, cv2.COLOR_BGR2GRAY)# 计算差异
diff = cv2.absdiff(img1_gray, img2_gray)# 阈值处理
_, thresh = cv2.threshold(diff, 15, 255, cv2.THRESH_BINARY)# 使用形态学操作去除噪声
kernel = np.ones((3, 3), np.uint8)
thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=2)# 查找差异区域的轮廓
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)# 绘制差异区域
for contour in contours:area = cv2.contourArea(contour)if area > 50:x, y, w, h = cv2.boundingRect(contour)cv2.rectangle(img2_color, (x, y), (x + w, y + h), (0, 0, 255), 2)# 显示结果
cv2.imshow('Differences', img2_color)
cv2.waitKey(0)
cv2.destroyAllWindows()

总结

通过上述修改,我们生成了两张复杂的“找不同”图片,只有一处细微的差异,并且这个差异不容易被发现。这样可以满足您对复杂度和隐蔽性的要求。

如果您希望进一步调整差异的难度或类型,可以根据需要修改代码中的参数和逻辑。

如有任何问题或需要进一步的帮助,请随时告诉我!

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

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

相关文章

AdaTAD(CVPR 2024)视频动作检测方法详解

前言 论文:End-to-End Temporal Action Detection with 1B Parameters Across 1000 Frames 代码:AdaTAD 从论文标题可以看出,AdaTAD 可以在 1B 参数且输入视频在 1000 帧的情况下实现端到端的训练,核心创新点是引入 Temporal-Inf…

STM32_实验4_控制蜂鸣器

1.设置 PB2 引脚,生成代码。 2.打开蜂鸣器 // 循环反复HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET); // 开启蜂鸣器printf("beep on\n");HAL_Delay(500); // 等待响500msHAL_GPIO_WritePin(…

解锁C++多态的魔力:灵活与高效的编码艺术(下)

文章目录 前言🎱四、多态的原理🔮4.1 虚函数表(vtable)🔮4.2 派生类对象中的虚函数表4.2.1 编写程序去访问虚函数表4.2.2 虚表存储位置的验证 🎱五、 多态的静态绑定和动态绑定🔮5.1 静态绑定&a…

spring底层原理

本文参考黑马程序员的spring底层讲解,想要更详细的可以去看视频。 另外文章会每日更新,大概持续1个月!!!每天更新一讲 这部分比较抽象,要经常复习!!! 一、BeanFactory与A…

【JPCS独立出版 | 福州大学主办 | 有确定的ISSN号】第三届可再生能源与电气科技国际学术会议(ICREET 2024)

第三届可再生能源与电气科技国际学术会议(ICREET 2024) 2024 3rd International Conference on Renewable Energy and Electrical Technology ICREET 2024已成功申请JPCS - Journal of Physics: Conference Series (ISSN:1742-6596) 独立出版&#xf…

引领智慧文旅新纪元,开启未来旅游新境界

融合创新科技,重塑旅游体验,智慧文旅项目定义旅游新未来 在全球化的浪潮中,旅游已成为连接世界的重要纽带。智慧文旅项目,不仅仅是一次技术的革新,更是对旅游行业未来发展的一次深刻思考。信鸥科技通过运用云计算、大数…

Vue3动态组件原来是这样

什么是Vue3动态组件 在Vue3中&#xff0c;动态组件简单来说就是根据不同的条件进行不同组件的渲染&#xff0c;可以联想一下在前端中常用到的动态样式 基本使用 在Vue3中&#xff0c;动态组件的使用也是非常简单的&#xff0c;只需要使用<component>标签&#xff0c;并…

WPFDeveloper正式版发布

WPFDeveloper WPFDeveloper一个基于WPF自定义高级控件的WPF开发人员UI库&#xff0c;它提供了众多的自定义控件。 该项目的创建者和主要维护者是现役微软MVP 闫驚鏵: https://github.com/yanjinhuagood 该项目还有众多的维护者&#xff0c;详情可以访问github上的README&…

Redis 高可用:从主从到集群的全面解析

目录 一、主从复制 (基础)1. 同步复制a. 全量数据同步b. 增量数据同步c. 可能带来的数据不一致 2. 环形缓冲区a. 动态调整槽位 3. runid4. 主从复制解决单点故障a. 单点故障b. 可用性问题 5. 注意事项a. Replica 主动向 Master 建立连接b. Replica 主动向 Master 拉取数据 二、…

STM32传感器模块编程实践(八) HX711压力传感器称重模块简介及驱动源码

文章目录 一.概要二.HX711主要技术指标三.HX711模块参考原理图四.模块接线说明五.模块工作原理介绍六.模块通讯协议介绍七.STM32单片机与HX711模块实现重量测量实验1.硬件准备2.软件工程3.软件主要代码4.实验效果 八.小结 一.概要 电子秤是将检测与转换技术、计算机技术、信息…

Python网络爬虫从入门到实战

目录 引言 一、网络爬虫的概念 二、 网络爬虫的基本工作流程 &#xff08;一&#xff09;过程&#xff1a; &#xff08;二&#xff09;安装requests模块和beautifulsoup4模块 &#xff08;三&#xff09;requests库的使用 1、requests库的基本介绍 2、导入requests库的…

一款零依赖、跨平台的流媒体协议处理工具,支持 RTSP、WebRTC、RTMP 等视频流协议的处理

大家好&#xff0c;今天给大家分享一款功能强大的流媒体协议处理工具go2rtc&#xff0c;支持多种协议和操作系统&#xff0c;具有零依赖、零配置、低延迟等特点。 项目介绍 go2rtc可以从各种来源获取流&#xff0c;包括 RTSP、WebRTC、HomeKit、FFmpeg、RTMP 等&#xff0c;并…

学习文档10/16

MySQL 字符集&#xff1a; MySQL 支持很多种字符集的方式&#xff0c;比如 GB2312、GBK、BIG5、多种 Unicode 字符集&#xff08;UTF-8 编码、UTF-16 编码、UCS-2 编码、UTF-32 编码等等&#xff09;。 查看支持的字符集 你可以通过 SHOW CHARSET 命令来查看&#xff0c;支持…

ARINC 429总线协议

一、概述 ARINC 是美国航空无线电公司英文字头的缩写&#xff0c; 该公司1977年7月21日出版了“ARINC 429规范”一书&#xff0c;429规范就是飞机电子系统之间数字式数据传输的标准格式&#xff0c;在飞机上使用429总线的电子设备均应遵守这个规范&#xff0c;这样才能保证电子…

Redis应用高频面试题

Redis 作为一个高性能的分布式缓存系统,广泛应用于后端开发中,因此在后端研发面试中,关于 Redis 的问题十分常见。 本文整理了30个常见的 Redis 面试题目,涵盖了 Redis 的源码、数据结构、原理、集群模式等方面的知识,并附上简要的回答,帮助大家更好地准备相关的面试。 …

2024年【N2观光车和观光列车司机】及N2观光车和观光列车司机模拟考试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 N2观光车和观光列车司机考前必练&#xff01;安全生产模拟考试一点通每个月更新N2观光车和观光列车司机模拟考试题题目及答案&#xff01;多做几遍&#xff0c;其实通过N2观光车和观光列车司机操作证考试很简单。 1、…

LabVIEW提高开发效率技巧----用户权限控制

在LabVIEW开发中&#xff0c;用户权限控制是一个重要的设计模块&#xff0c;尤其在多用户系统中&#xff0c;它可以确保数据安全并控制不同用户的操作权限。为了实现用户权限控制&#xff0c;可以通过角色与权限管理模块来进行设计和实施。以下将从多个角度详细说明如何在LabVI…

Sentinel 快速入门

前置推荐阅读:Sentinel 介绍-CSDN博客 前置推荐阅读&#xff1a;Nacos快速入门-CSDN博客 快速开始 欢迎来到 Sentinel 的世界&#xff01;这篇新手指南将指引您快速入门 Sentinel。 Sentinel 的使用可以分为两个部分: 核心库&#xff08;Java 客户端&#xff09;&#xff1a…

新版vs code + Vue高亮、语法自动补全插件

vs code 版本或及以上 安装以下三个插件插件 Vetur Vue语法支持。包括语法高亮、语法代码提示、语法lint检测 ESLint语法纠错 Prettier 2.左下角设置 3.进行配置 配置内容&#xff1a; {"editor.fontSize": 20,"window.zoomLevel": 1,"workben…

Windows】【DevOps】Windows Server 2022 采用WinSW 启动一个会创建新的控制台程序窗口的程序行为分析

WinSW使用参考 【Windows】【DevOps】Windows Server 2022 采用WinSW将一个控制台应用程序作为服务启动&#xff08;方便&#xff09;-CSDN博客 源码 调整ConsoleApp1程序源代码如下&#xff1a; using System; using System.Diagnostics; using System.IO; using System.R…