国粹的复现

看到这道题目的时候我有点茫然,不知道从什么地方开始下手,经过师傅的提示,我们先要做出一个坐标,根据题目.png总共有42种,而题目.png有两层,猜测第一层为Y轴,第二层为X轴,所以我们先要对题目.png进行切片,方便我们进行图片识别。

我们先创建一个新的文件夹 ,用来存储切出来的图片。

第三方是pillow,我们需要提前准备好。

如果安装的时候太慢了就可以换一下源,简单的提供了几个

清华:https://pypi.tuna.tsinghua.edu.cn/simple

阿里云:https://mirrors.aliyun.com/pypi/simple/

中国科技大学:https:pypi.mirrors.ustc.edu.cn/simple/

eg:pip install pillow -i +镜像源

import os
from PIL import Image
 
pic=Image.open('C:\\Users\\86187\\Desktop\\123.png')
x=0
y=0
for i in range(0,42):
    #m=Image.new('RGB',(431,73))
    n=pic.crop((x,y,x+53,y+73))
    n.save(f'C:\\Users\\86187\\Desktop\\cuted\\{i}.png')
    x+=53

 此时我们就需要知道a和k里面有多少张麻将,刚开始就慢慢去数,之后发现一个比较快的方法,这里我们会发现每张图片的大小都是一样的,看到图片宽的像素值是18073,18073的因式分解为11*31*53,再去看看第一张麻将和第二张麻将,宽度的界限值差不多是五十左右,说明其中的一个因子大概率是53,所以18073除以53是341,所以a和k里面的麻将数量都是341。

再去看看题目.png下面的一排多了一张一万的,后面的是以123的顺序进行排列的,所以第二排的第一张是没有什么用的。

于是将a与k图像进行识别匹配,并将坐标保存,绘制为图像

这里需要用到python的第三方库,opencv2

import cv2
import numpy as np
import os
import turtle as t
import time
images=[]
x=[0 for i in range(343)]
y=[0 for i in range(343)]
 
 
for cuedir,dirs,filename in os.walk('C:\\Users\\86187\\Desktop\\cuted'):
    for files in filename:
        f=eval(files.split(".")[0])#将.前面文件名单独储存,并化为数字
        images.append(f)#储存文件夹内的图片名称
images.sort()#整理文件名顺序
 
 
img_rgb = cv2.imread('C:\\Users\\86187\\Desktop\\a.png')#识别图
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
#shape函数是numpy.core.fromnumeric中的函数,它的功能是读取矩阵的长度
for i in range(len(images)):
    template = cv2.imread(f'C:\\Users\\86187\\Desktop\\cuted\\{images[i]}.png', 0)  # 识别模板
    h, w = template.shape[:2]  # 读取宽高
    result = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)#标准相关匹配
    threshold = 0.9
    # 取匹配程度大于%90的坐标
    loc = np.where(result >= threshold)
    #print(loc)
    # np.where返回的坐标值(x,y)是(h,w),注意h,w的顺序
    for pt in zip(*loc[::-1]):
        #print(pt)
        m=pt[0]//53
        x[m]=images[i]
        bottom_right = (pt[0] + w, pt[1] + h)
        cv2.rectangle(img_rgb, pt, bottom_right, (0, 0, 255), 2)
cv2.imwrite("C:\\Users\\Lenovo\\Desktop\\x.jpg", img_rgb)
img_rgb = cv2.imread('C:\\Users\\86187\\Desktop\\k.png')#识别图
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
#shape函数的功能是读取矩阵的长度
for i in range(len(images)):
    template = cv2.imread(f'C:\\Users\\86187\\Desktop\\cuted\\{images[i]}.png', 0)  # 识别模板
    h, w = template.shape[:2]  # 读取宽高
    result = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)#标准相关匹配
    threshold = 0.9
    # 取匹配程度大于%90的坐标
    loc = np.where(result >= threshold)
    #print(loc)
    # np.where返回的坐标值(x,y)是(h,w),注意h,w的顺序
    for pt in zip(*loc[::-1]):
        #print(pt)
        m=pt[0]//53
        y[m]=images[i]
        bottom_right = (pt[0] + w, pt[1] + h)
        cv2.rectangle(img_rgb, pt, bottom_right, (0, 0, 255), 2)
cv2.imwrite("C:\\Users\\86187\\Desktop\\y.jpg", img_rgb)#保存识别后的图片
cv2.waitKey(0)
for i in range(0,343):
    print(f'{x[i]} {y[i]}')
'''with open('C:\\Users\\86187\\Desktop\\gnuplot.txt','w') as gn:
    for i in range(0,342):
        gn.write(f'{x[i]} {y[i]}\n')#坐标导出为一个txt文件'''
#绘制模块
t.speed(100)
t.pu()
for i in range(0,343):
    t.goto(y[i]*5,-x[i]*5)
    t.pd()
    t.circle(1,360)
    t.pu()
time.sleep(1000)#方便截图

最后的结果:flag{202305012359}

我们也可以看看其它师傅的方法

import io
import hashlib

path = "C:\\Users\\HK\\Desktop\\a.png"
im = Image.open(path)
width = im.width
height = im.height

block_width = 53
block_height = 73

md5_list = []
for x in range(0, width, block_width):
    tmp = im.crop((x, 0, x + block_width, height))
    with io.BytesIO() as output:
        tmp.save(output, format="JPEG")
        binary_data = output.getvalue()
        md5 = hashlib.md5(binary_data).hexdigest()
        md5_list.append(md5)

tmp_list = []

for i in range(len(md5_list)):
    if md5_list[i] != md5_list[i - 1]:
        tmp_list.append(md5_list[i])

alpbet_list = {}
for i in range(len(tmp_list)):
    alpbet_list[tmp_list[i]] = str(i)


path_a = "C:\\Users\\HK\\Desktop\\a.png"
im = Image.open(path_a)
width = im.width

out_x = []
for x in range(0, width, block_width):
    tmp = im.crop((x, 0, x + block_width, height))
    with io.BytesIO() as output:
        tmp.save(output, format="JPEG")
        binary_data = output.getvalue()
        md5 = hashlib.md5(binary_data).hexdigest()
    try:
        out_x .append(alpbet_list[md5])
    except:
        pass

path_k = "C:\\Users\\HK\\Desktop\\k.png"
im = Image.open(path_k)
width = im.width

out_y = []
for x in range(0, width, block_width):
    tmp = im.crop((x, 0, x + block_width, height))
    with io.BytesIO() as output:
        tmp.save(output, format="JPEG")
        binary_data = output.getvalue()
        md5 = hashlib.md5(binary_data).hexdigest()
    try:
        out_y.append(alpbet_list[md5])
    except:
        out_y.append("0")

out = Image.new("RGB",(100,50),"white")
for i in range(len(out_x)):
    x = int(out_x[i])
    y = int(out_y[i])
    out.putpixel((x,y),(0,0,0))

out.save("out.png")

 

师傅的 主要的思路是a是x坐标,k是y坐标

所以这道题主要是要建立起坐标。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值