本文共 1966 字,大约阅读时间需要 6 分钟。
比赛时间:2020年10月17日早上9点
比赛时限:一个月
宣传单里藏有flag,不过分成了三份
拼好如图:
工具:
与佛论禅:
下载文件
得到一种图片
将图片后缀名改成rar,用WinRAR打开(或者用,显然图片里藏有其他东西,或者foremost得到一个压缩包()) ,里面是一张错位的二维码
位置调整
扫描得到flag
给了一张图片source.jpg和一个压缩包,压缩包里为1600个小图片,这1600个小图片是将source.jpg 编辑 加上flag以后的图片切割得来的。
利用python的CV2库的图像匹配算法,由于修改原图,将flag写入到图片上会造成小图片与原图上相应位置的图片匹配度降低,当匹配度低于某个阈值时,可认为是将flag写到了这张小图片上,阈值取的是5e-10.。
同时将小图片拼接成原图片并且保存。
因为开启多线程,比较时间较短,但运行时比较占CPU
# python3import cv2from PIL import Imageimport numpy as npimport osimport shutilimport threading# 读取目标图片source = cv2.imread(r"C:/Users/Lenovo/Desktop/pt/source.jpg")# 拼接结果target = Image.fromarray(np.zeros(source.shape, np.uint8))# 图库目录dirs_path = r"C:/Users/Lenovo/Desktop/pt/pingTu"# 差异图片存放目录dst_path = r"C:/Users/Lenovo/Desktop/pt/new1"def match(temp_file): # 读取模板图片 template = cv2.imread(temp_file) # 获得模板图片的高宽尺寸 theight, twidth = template.shape[:2] # 执行模板匹配,采用的匹配方式cv2.TM_SQDIFF_NORMED result = cv2.matchTemplate(source, template, cv2.TM_SQDIFF_NORMED) # 归一化处理 cv2.normalize(result, result, 0, 1, cv2.NORM_MINMAX, -1) # 寻找矩阵(一维数组当做向量,用Mat定义)中的最大值和最小值的匹配结果及其位置 min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result) target.paste(Image.fromarray(template), min_loc) return abs(min_val)class MThread (threading.Thread): def __init__(self, file_name): threading.Thread.__init__(self) self.file_name = file_name def run(self): real_path = os.path.join(dirs_path, k) rect = match(real_path) if rect > 5e-10: print(rect) shutil.copy(real_path, dst_path)count = 0dirs = os.listdir(dirs_path)threads = []for k in dirs: if k.endswith('jpg'): count += 1 print("processing on pic"+str(count)) mt = MThread(k) mt.start() threads.append(mt) else: continue# 等待所有线程完成for t in threads: t.join()target.show()target.save(r"C:/Users/Lenovo/Desktop/pt/target.jpg")
拼接结果(不知道为什么存在色差)需要手动拼合部分内容
转载地址:http://onwof.baihongyu.com/