将像素坐标转换为帧坐标

2024-04-20 01:02:24 发布

您现在位置:Python中文网/ 问答频道 /正文

我用一个小窗口来检测马里奥,它由一个红色的方块表示。但是,该红色块由16×12像素组成。我想获取我找到的像素坐标,并根据图像中显示的窗口将其转换为正常的x/y坐标系:Actual frame,它应该是13×16网格(不是像素)。你知道吗

例如,如果马里奥盒子在屏幕的左上角,坐标应该是0,0。你知道吗

我也不知道如何制作网格。你知道吗

我使用的代码如下:

import numpy as np
from PIL import Image


class MarioPixels:

def __init__(self):
    self.mario = np.array([

        [[248, 56, 0],
         [248, 56, 0],
         [248, 56, 0],
         [248, 56, 0],
         [248, 56, 0],
         [248, 56, 0],
         [248, 56, 0],
         [248, 56, 0],
         [248, 56, 0],
         [248, 56, 0],
         [248, 56, 0],
         [248, 56, 0],
         [248, 56, 0],
         [248, 56, 0],
         [248, 56, 0],
         [248, 56, 0]
         ]]
    )

    self.height = len(self.mario)  # specify number of pixels for columns in the frame
    self.width = len(self.mario[0])  # specificy number of pixels representing a line in the frame

    print(self.mario.shape)

# find difference in R, G and B values between what's in window and what's on the frame
def pixelDiff(self, p1, p2):
    return abs(p1[0] - p2[0]), abs(p1[1] - p2[1]), abs(p1[2] - p2[2])

def isMario(self, window, pattern):
    total = [0, 0, 0]
    count = 0
    for line in range(len(pattern)):

        lineItem = pattern[line]
        sample = window[line]

        for pixelIdx in range(len(lineItem)):
            count += 1
            pixel1 = lineItem[pixelIdx]
            pixel2 = sample[pixelIdx]
            d1, d2, d3 = self.pixelDiff(pixel1, pixel2)
            # print(pixelIdx)
            total[0] = total[0] + d1  # sum of difference between all R values found between window and frame
            total[1] = total[1] + d2  # sum of difference between all G values found between window and frame
            total[2] = total[2] + d3  # sum of difference between all B values found between window and frame
            # Mario has a red hat
            # if line == 0 and pixelIdx == 4 and pixel2[0] != 248:
            #    return 1.0

    rscore = total[0] / (
                count * 255)  # divided by count of all possible places the R difference could be calculated
    gscore = total[1] / (
                count * 255)  # divided by count of all possible places the G difference could be calculated
    bscore = total[2] / (
                count * 255)  # divided by count of all possible places the B difference could be calculated

    return (
                       rscore + gscore + bscore) / 3.0  # averaged to find a value between 0 and 1. Num close to 0 means object(mario, pipe, etc.) is there,
    # whereas, number close to 1 means object was not found.

def searchForMario(self, step, state, pattern):

    height = self.height
    width = self.width

    x1 = 0
    y1 = 0
    x2 = width
    y2 = height

    imageIdx = 0
    bestScore = 1.1
    bestImage = None
    bestx1, bestx2, besty1, besty2 = 0, 0, 0, 0

    for y1 in range(0, 240 - height, 8):  # steps in range row, jump by 8 rows
        y2 = y1 + height

        for x1 in range(0, 256 - width, 3):  # jump by 3 columns
            x2 = x1 + width

            window = state[y1:y2, x1:x2, :]
            score = self.isMario(window, pattern)
            # print(imageIdx, score)
            if score < bestScore:
                bestScore = score
                bestImageIdx = imageIdx
                bestImage = Image.fromarray(window)
                bestx1, bestx2, besty1, besty2 = x1, x2, y1, y2

            imageIdx += 1

    bestImage.save('testrgb' + str(step) + '_' + str(bestImageIdx) + '_' + str(bestScore) + '.png')

    return bestx1, bestx2, besty1, besty2

Tags: andoftheinselfcountbetweenall
1条回答
网友
1楼 · 发布于 2024-04-20 01:02:24

它看起来像是有一个像素宽高比,所以每个像素块的宽度和高度是不同的。你知道吗

按照你的代码,你的像素空间是256x240像素,但你说它实际上代表一个13x16的网格。这意味着x域中的每个块是(256/13)或大约20像素,而y域中的每个块是(240/16)15像素。这意味着16x12像素的“Mario”所占的块还不到一个完整的块。看看你的形象,这似乎是一种可能性-灌木和云也占据不到一个街区。你知道吗

我建议您首先确保13x16网格是正确的(只是因为它似乎与您的像素大小不完全匹配,并且因为您范围内的跨距大小意味着块实际上可能是3x8像素)。然后,您可以尝试将网格添加到像素图像,只需将x坐标可被20整除的每个像素的值设置为黑色RGB像素的(0,0,0)值(以及y坐标可被15整除的值-使用模运算符%)。要得到“块”坐标,只需将x坐标除以20,y坐标除以15,然后四舍五入到最接近的整数(或使用//作为除法的一部分进行四舍五入)。你知道吗

我假设你的像素坐标也从左上角(0,0)到右下角(256,240)。你知道吗

相关问题 更多 >