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

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

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

改进思路

  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.rhkb.cn/news/451738.html

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

相关文章

vue使用jquery的ajax,页面跳转

一、引入jquery依赖 打开终端更新npm npm install -g npm 更新完后引入输入npm install jquery 加载完后 在最外层的package.json文件中加入以下代码 配置好后导入jquery 设置变量用于接收服务器传输的数据 定义ajax申请数据 服务器的Controller层传输数据 (…

【Java 并发编程】单例模式

前言 单例模式是一种十分常用但却相对而言比较简单的单例模式。虽然它简单但是包含了关于线程安全、内存模型、类加载机制等一些比较核心的知识点。本章会介绍单例模式的设计思想,会去讲解了几种常见的单例实现方式,如饿汉式、懒汉式、双重检锁、静态内部…

【大模型】AI视频课程制作工具开发

1. 需求信息 1.1 需求背景 讲师们在制作视频的过程中,发现录制课程比较麻烦,要保证环境安静,保证录制过程不出错,很容易反复重复录制,为了解决重复录制的工作量,想通过 ai 课程制作工具,来解决…

数据轻松上云——Mbox边缘计算网关

随着工业4.0时代的到来,工厂数字化转型已成为提升生产效率、优化资源配置、增强企业竞争力的关键。我们凭借其先进的边缘计算网关与云平台技术,为工厂提供了高效、稳定的数据采集与上云解决方案。本文将为您介绍Mbox边缘计算网关如何配合明达云平台&…

【CS常见问题】你用的是VS2019,最高支持.NET5.0,但是项目将.NET6.0设为目标无法运行,怎么办?

.NET版本问题 报错示例报错分析最简单的方法步骤 报错示例 严重性 代码 说明 项目 文件 行 禁止显示状态 错误 NETSDK1045 当前 .NET SDK 不支持将 .NET 6.0 设置为目标。请将 .NET 5.0 或更低版本设置为目标,或使用支持 .NET 6.0 的 .NET SDK 版本。 ABFview C:\x…

◇【论文_20150225】 DQN_2015(nature) 〔Google DeepMind〕

整理代码 1:DQN CartPole_v1.ipynb https://www.nature.com/articles/nature14236 Human-level control through deep reinforcement learning 文章目录 摘要主体:要做什么 如何做的 要点keypoints实验 与 评估2 个指标和 各游戏的最好方法比较t-S…

【Linux网络编程】Socket编程--UDP(第一弹):实现客户端和服务器互相发送消息

🌈个人主页: 南桥几晴秋 🌈C专栏: 南桥谈C 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据…

.Net自动更新程序GeneralUpdate,适用于wpf,winfrom,控制台应用

GeneralUpdate是基于.net framwork4.5.2开发的一款(c/s应用)自动升级程序。 第一个版本叫Autoupdate 有人会奇怪为什么会改名称,稍微解释一下是因为在nuget上有重名的项目再者就是新版本更新功能不仅限于wpf程序的更新。 将更新的核心部分抽…

《Knowledge Perceived Multi-modal Pretraining in E-commerce》中文校对版

文章中文化系列目录 文章目录 文章中文化系列目录摘要CCS概念:关键词:1 引言2 相关工作2.1 多模态预训练2.2 知识图谱增强的预训练模型 3 方法3.1 模态编码层3.1.1 图像初始特征3.1.2 文本初始特征3.1.3 知识的表面形式特征 3.2 模态交互层3.2.1 图像模态…

day02 -- docker

1.docker的介绍 Docker 是一个开源的应用容器引擎,基于 Go语言 并遵从 Apache2.0 协议开源。Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使…

填充与步幅

一个3x3的卷积核对6X6的图像进行卷积,得到一个4x4的图像 此时,生成图像长或宽 ln-f1 使用过滤器对图像进行卷积出现的问题有: 每次卷积后图像都会变小,当网络过深的时候,就会遗失许多像素 过滤器对边缘像素访问仅一…

基于C#开发游戏辅助工具的Windows底层相关方法详解

开发游戏辅助工具通常需要深入了解Windows操作系统的底层机制,以及如何与游戏进程进行有效交互。本文将基于C#语言,从Windows底层方法的角度来详细讲解开发游戏辅助工具的相关技术和概念。 一、游戏辅助工具的基本概述 游戏辅助工具,通常被称…

网络学习笔记

一、网络的结构与功能 网络的鲁棒性与抗毁性 如果在移走少量节点后网络中的绝大部分节点仍然是连通的,那么就该网络的连通性对节点故障具有鲁棒性 网络上的动力学 动力系统:自旋、振子或混沌的同步、可激发系统 传播过程:信息传播与拥堵…

git命令使用一览【自用】

git常见操作: git initgit remote add master【分支名字】 gitgits.xxxxx【仓库中获取的ssh链接或者http协议的链接】检查远程仓库是否链接成功。 git remote -v出现以下画面就可以git pull,git push了

可以与 FastAPI 不分伯仲的 Python 著名的 Web 框架

正如你所理解的,任何领域都不可能停止进步,不断使用相同的工具意味着不思进取。这一点在信息技术领域,尤其是网络开发行业非常明显。 关于网络框架,不论是 Django 和 Flask 等传统框架还是 Python 的新型高级框架,一直…

Semantic Kernel进阶:将ChatCompletion(聊天完成)服务添加到你的AI项目(三)

文章目录 Semantic Kernel进阶:将聊天完成服务添加到你的AI项目一、引言二、聊天完成服务的重要性三、基本介绍3.1 创建聊天完成服务3.2 依赖注入方式3.3 创建独立的服务实例 四、实战4.1 检索聊天完成服务4.2 使用聊天完成服务4.2.1 非流式4.2.2 流式 4.3 完整代码…

Mybatis多对一查询的配置及两种方法的使用示例对比以及Mybatis一对多查询两种方法使用示例及对比

一、Mybatis多对一查询的配置及两种方法的使用示例对比 为了试验Mybatis多对一的查询,我们先在数据库中建两个表,一个城市表,一个市区表,一个城市有多个区是一个一对多的关系;多个区对应一个城市是一个多对一的关系。建…

第五届光学与图像处理国际学术会议(ICOIP 2025)征稿中版面有限!

第五届光学与图像处理国际学术会议(ICOIP 2025) 2025 5th International Conference on Optics and Image Processing (ICOIP 2025) 重要信息 时间地点:2025年4月25-27日丨中国西安 截稿日期:2024年12月16日23:59 …

vue3项目使用百度地图实现地图选择功能代码封装(开箱即用)

vue3项目使用百度地图实现地图选择功能代码封装方案(开箱即用) <template><div class="bmapgl">

【软件测试】JUnit

Junit 是一个用于 Java 编程语言的单元测试框架&#xff0c;Selenium是自动化测试框架&#xff0c;专门用于Web测试 本篇博客介绍 Junit5 文章目录 Junit 使用语法注解参数执行顺序断言测试套件 Junit 使用 本篇博客使用 Idea集成开发环境 首先&#xff0c;创建新项目&#…