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

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

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

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

改进思路

  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.kler.cn/news/356331.html

相关文章:

  • C# 文件操作
  • MyBatis 中updateByPrimaryKey和updateByPrimaryKeySelective区别
  • iPhone照片内存怎么清理,参考这些方法
  • MySQL在5.6为啥引入索引条件下推
  • Quant星球-量化连载
  • WPF中MVVM的应用举例
  • .NET 9 - 尝试一下Open Api 的一些变化
  • 配置啊手动阀打发第三方
  • SpringBoot物流管理平台开发全解析
  • 网站防护,高可用,雷池配置同步教程
  • 创新的语音情感识别:利用 WavLM Large 探索性别信息整合和高级汇集方法
  • 尚硅谷rabbitmq2024 工作模式发布订阅模式 第10节答疑
  • Python爬虫-eBay商品排名数据
  • 线性可分支持向量机的原理推导 标准优化目标 公式解析
  • JavaSE之String类
  • 将MySQL中按行记录的数据转换成按列记录
  • 【EJS】JavaScript 模板引擎
  • DC系列靶机-DC6
  • 深度学习代码学习笔记2
  • 超详细的Java Web开发