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
相关产品推荐
相关产品推荐

