You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python类中已定义img却报'img is not defined'错误的解决求助

问题:列表推导式中出现img is not defined错误

编写了一段扫描图片生成emoji迷宫的Python代码,已定义img变量,但运行时在列表推导式行for c in xrange if c < img.shape[1]] for r in yrange if r < img.shape[0]]处出现img is not defined错误,完整代码如下:

import numpy as np
import cv2
import matplotlib.pyplot as plt
def downloadImage(URL):
    """Downloads the image on the URL, and convers to cv2 RGB format"""
    from io import BytesIO
    from PIL import Image as PIL_Image
    import requests

    response = requests.get(URL)
    image = PIL_Image.open(BytesIO(response.content))
    return cv2.cvtColor(np.array(image), cv2.COLOR_BGR2RGB)


URL = "https://cdn.discordapp.com/attachments/670656848256434176/1001139167159406602/maze2.png"


img = downloadImage(URL)

# Convert ot 2 color
img = cv2.cvtColor(np.array(img), cv2.COLOR_BGR2GRAY)
ret3, th3 = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY)
# plt.imshow(th3, cmap='gray')

# Detect corners
CornerKernel = np.ones((3, 3), np.uint8)
corner = cv2.filter2D(th3//255, -1, CornerKernel)
# A corner add up to to 1 or 9
Corners = np.argwhere((corner == 4) | (corner == 8))
antiCorners = np.argwhere((corner == 1) | (corner == 5))
# for each point in Corners, find the closet point in antiCorners
Corner_antiCorner = []
for point in Corners:
    distances = np.linalg.norm(antiCorners-point, axis=1)
    closest = antiCorners[np.argmin(distances)]
    Corner_antiCorner.append((point+closest)/2)
    plt.plot([point[1], closest[1]], [point[0], closest[0]], color='r')
# For eachpoint in Corner_antiCorner, find the closet point in Corner_antiCorner
closestCorners = []
for point in Corner_antiCorner:
    distances = np.linalg.norm(Corner_antiCorner-point, axis=1)
    # closest is itself, so second closest is chosen
    closest = Corner_antiCorner[distances.argsort()[1]]
    closestCorners.append((point, closest))
    plt.plot([point[1], closest[1]], [point[0], closest[0]], color='r')

# Sample of separations dx,dy
dx = np.array([abs(p[1]-q[1]) for p, q in closestCorners])
dy = np.array([abs(p[0]-q[0]) for p, q in closestCorners])

mediandx = np.median(dx[dx > 0])
mediandy = np.median(dy[dy > 0])

print("is this working")
stepY, stepX = int(mediandy), int(mediandx)
xrange = range(stepX//2, img.shape[0], stepX)
yrange = range(stepY//2, img.shape[1], stepY)
x, y = [], []
mazeElement = {0: ':black_large_square:', 1: ':white_large_square:'}

print('for loop 1')
for r in yrange:
    for c in xrange:
        x.append(c)
        y.append(r)

plt.scatter(x, y)

print('for loop 2cd')

self.base_map = [[mazeElement[img[r, c]//255]
            for c in xrange if c < img.shape[1]] for r in yrange if r < img.shape[0]]

修复方案

1. 核心错误原因

代码中使用了self.base_map,但这段代码并未封装在类的方法内部,self是类实例的专属引用,在非类环境下使用会导致解释器上下文混乱,间接引发img is not defined的错误。

2. 其他需要修正的问题

  • 索引范围搞反:xrange基于img.shape[0](图像高度/行数),但c是列索引,应对应img.shape[1](图像宽度/列数);yrange基于img.shape[1],但r是行索引,应对应img.shape[0],范围定义错误会导致后续像素索引越界。
  • 使用错误的图像变量:二值化后的结果是th3,应该用它来获取像素值,而非原始灰度图img。

3. 修正后的完整代码

import numpy as np
import cv2
import matplotlib.pyplot as plt

def downloadImage(URL):
    """Downloads the image on the URL, and converts to cv2 RGB format"""
    from io import BytesIO
    from PIL import Image as PIL_Image
    import requests

    response = requests.get(URL)
    image = PIL_Image.open(BytesIO(response.content))
    return cv2.cvtColor(np.array(image), cv2.COLOR_BGR2RGB)


URL = "https://cdn.discordapp.com/attachments/670656848256434176/1001139167159406602/maze2.png"

img = downloadImage(URL)

# Convert to 2 color
img = cv2.cvtColor(np.array(img), cv2.COLOR_BGR2GRAY)
ret3, th3 = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY)
# plt.imshow(th3, cmap='gray')

# Detect corners
CornerKernel = np.ones((3, 3), np.uint8)
corner = cv2.filter2D(th3//255, -1, CornerKernel)
# A corner adds up to 4 or 8
Corners = np.argwhere((corner == 4) | (corner == 8))
antiCorners = np.argwhere((corner == 1) | (corner == 5))

# For each point in Corners, find the closest point in antiCorners
Corner_antiCorner = []
for point in Corners:
    distances = np.linalg.norm(antiCorners - point, axis=1)
    closest = antiCorners[np.argmin(distances)]
    Corner_antiCorner.append((point + closest)/2)
    plt.plot([point[1], closest[1]], [point[0], closest[0]], color='r')

# For each point in Corner_antiCorner, find the closest point in Corner_antiCorner
closestCorners = []
for point in Corner_antiCorner:
    distances = np.linalg.norm(Corner_antiCorner - point, axis=1)
    # Skip self, take second closest
    closest = Corner_antiCorner[distances.argsort()[1]]
    closestCorners.append((point, closest))
    plt.plot([point[1], closest[1]], [point[0], closest[0]], color='r')

# Sample of separations dx,dy
dx = np.array([abs(p[1]-q[1]) for p, q in closestCorners])
dy = np.array([abs(p[0]-q[0]) for p, q in closestCorners])

mediandx = np.median(dx[dx > 0])
mediandy = np.median(dy[dy > 0])

print("is this working")
stepY, stepX = int(mediandy), int(mediandx)
# 修正xrange和yrange的范围:x对应列(shape[1]),y对应行(shape[0])
xrange = range(stepX//2, img.shape[1], stepX)
yrange = range(stepY//2, img.shape[0], stepY)
x, y = [], []
mazeElement = {0: ':black_large_square:', 1: ':white_large_square:'}

print('for loop 1')
for r in yrange:
    for c in xrange:
        x.append(c)
        y.append(r)

plt.scatter(x, y)

print('for loop 2cd')

# 去掉self,使用th3获取二值化后的像素值,同时修正索引判断
base_map = [[mazeElement[th3[r, c]//255]
            for c in xrange if c < img.shape[1]] 
            for r in yrange if r < img.shape[0]]

# 可选:打印生成的emoji迷宫
for row in base_map:
    print(''.join(row))

内容的提问来源于stack exchange,提问作者Dre

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 06:09:20