迷路识别是缓慢的,识别并不总是acu

2024-04-28 05:11:29 发布

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

我正在制作一个Python脚本:

  1. 从文件中获取图像
  2. 寻找纸张(由openCV完成)
  3. 扭曲图像
  4. 裁剪纸张的边距
  5. 在一行像素中寻找最小数量的白色像素,以弥补网格中单个字段的宽度/高度(逐像素)
  6. 基于每个字段中的平均像素RGB值(逐像素)重新创建迷宫,并将其保存到文件中
  7. 它显示了CLI中0和1的网格

当我在原始图像(5.2MB,4000x3000)上做的时候,它需要20秒(虽然我有相当快的8核ryzen cpu),实际上我只需要输出(0或1格)。如何加快进程,因为它将运行在树莓皮和它只需要几秒钟左右完成?我知道这段代码很长,但是它被分成了描述的部分,所以应该很容易阅读

#LIBRARY IMPORT
import math
import turtle                   
import time
import sys
from collections import deque
import numpy as np
from skimage import exposure
import argparse
import imutils
import cv2
from PIL import Image, ImageDraw

#LOAD THE FIRST IMAGE
image = cv2.imread("./image3.jpg")
ratio = image.shape[0] / 600.0
orig = image.copy()
image = imutils.resize(image, height = 600)

#Range of the colors of paper
lower = [160, 160, 160]
upper = [255,255,255]

#create array from ranges
lower = np.array(lower, dtype="uint8")
upper = np.array(upper, dtype="uint8")

#finding contours
mask = cv2.inRange(image, lower, upper)
output = cv2.bitwise_and(image, image, mask=mask)
ret,thresh = cv2.threshold(mask, 40, 255, 0)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
contours = max(contours, key = cv2.contourArea)
cnt = contours
rect = cv2.minAreaRect(cnt)
box = cv2.boxPoints(rect)
box = np.int0(box)
for c in [contours]:

#contour approximation
   peri = cv2.arcLength(c, True)
   approx = cv2.approxPolyDP(c, 0.01 * peri, True)

#crop of contour with 4 points
   if len(approx) == 4:
      screenCnt = approx
      break
img = cv2.drawContours(image,[screenCnt],0,(0,0,255),2)
print(screenCnt)
pts = screenCnt.reshape(4, 2)
rect = np.zeros((4, 2), dtype = "float32")
s = pts.sum(axis = 1)
rect[0] = pts[np.argmin(s)]
rect[2] = pts[np.argmax(s)]
diff = np.diff(pts, axis = 1)
rect[1] = pts[np.argmin(diff)]
rect[3] = pts[np.argmax(diff)]
rect *= ratio
(tl, tr, br, bl) = rect
widthA = np.sqrt(((br[0] - bl[0]) ** 2) + ((br[1] - bl[1]) ** 2))
widthB = np.sqrt(((tr[0] - tl[0]) ** 2) + ((tr[1] - tl[1]) ** 2))
heightA = np.sqrt(((tr[0] - br[0]) ** 2) + ((tr[1] - br[1]) ** 2))
heightB = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2))
maxWidth = max(int(widthA), int(widthB))
maxHeight = max(int(heightA), int(heightB))
dst = np.array([
   [0, 0],
   [maxWidth - 1, 0],
   [maxWidth - 1, maxHeight - 1],
   [0, maxHeight - 1]], dtype = "float32")
M = cv2.getPerspectiveTransform(rect, dst)
warp = cv2.warpPerspective(orig, M, (maxWidth, maxHeight))
warp = imutils.resize(warp)
cv2.imshow("image", image)
cv2.moveWindow("image",0,450)
cv2.imwrite("warp.jpg",warp)

#warping of found labyrinth
warp = cv2.imread("warp.jpg",0)
warp = cv2.medianBlur(warp,5)
ret,warp = cv2.threshold(warp,170,255,cv2.THRESH_BINARY)
cv2.imwrite("warp.jpg",warp)
image_file = "warp.jpg"
im = Image.open(image_file)
width, height = im.size
T = height*(5/210)
B = height-(height*(5/210))
L = width*(5/210)
R = width-(width*(5/210))
im_crop = im.crop((L, T, R, B))
im=im_crop
im_crop.save('warp.png', quality=100)
white=0

#finding field-size 
im = Image.open("warp.png")
width, height = im.size
minimalGridWidth2 = width
minimalGridWidth = width
MaximumGridWidth = width
for y in range (0, height):
   for x in range (0, width):
      if im.getpixel((x,y)) > 200:
         white = white+1
   if white <= minimalGridWidth:
      minimalGridWidth = white

#checks out how many X how many fields the labirynt has, checks what's the average value (more black or more white) is there on that field and recreates the new "ideal" labyrinth from this data
gridWidth = int(round(width/minimalGridWidth))
gridHeight = int(round(height/minimalGridWidth))
print(gridWidth)|
print(gridHeight)
newHeight = 0
newWidth = 0
newHeight=(minimalGridWidth*gridHeight)
newWidth=(minimalGridWidth*gridWidth)
print(minimalGridWidth)
print(newWidth)
print(newHeight)
im = im.resize((newWidth, newHeight), Image.ANTIALIAS)
i=0
x, y = gridWidth, gridHeight
pixelcount = [[0 for x in range(0,gridWidth)] for y in range(0,gridHeight)]
pixelavg = [[0 for x in range(0,gridWidth)] for y in range(0,gridHeight)]
print(pixelcount)
for y in range (0, gridHeight):
   for x in range (0, gridWidth):
      i=0
      pixel=0
      for v in range (0, minimalGridWidth):
         for w in range (0, minimalGridWidth):
            pixel=pixel+im.getpixel((((x*minimalGridWidth)+w),((y*minimalGridWidth)+v)))
            i=i+1
      if (pixel/i)<127:
         pixelavg[y][x]=1
      elif (pixel/i)>127:
         pixelavg[y][x]=0
print(np.array(pixelavg))
y,x,v,w,i=0,0,0,0,0
im2 = Image.new('RGB',(newWidth,newHeight),'white')
for y in range (0, gridHeight):
   for x in range (0, gridWidth):
      for v in range (0, minimalGridWidth):
         for w in range (0, minimalGridWidth):
            pixelx=pixelavg[y][x]
               if pixelx==0:
                  pixelDoc=(255,255,255)
               if pixelx==1:
                  pixelDoc=(0,0,0)
               Xw=((x*minimalGridWidth)+w)
               Yh=((y*minimalGridWidth)+v)
               im2.putpixel((Xw,Yh),pixelDoc) 
im2.save('warp3.png',quality=100)
imx=cv2.imread('warp3.png',0)
cv2.imshow('finito',imx)
cv2.imwrite('koniec.png',imx)
cv2.moveWindow("finito",750,450)
warp=cv2.imread("warp.png",0)
cv2.imshow("warp",warp)
cv2.moveWindow("warp",450,450)

Tags: inrectimageimportfornprangewidth
1条回答
网友
1楼 · 发布于 2024-04-28 05:11:29

当您关心性能或希望优化代码时,它可以帮助您分析程序。
您可以使用Python's profiler或带有PyCharm这样的探查器的IDE。
在4000x2665映像上分析代码时,我发现以下内容:

enter image description here

如您所见,getpixelputpixel函数占用了大约60%的执行时间。
这是有意义的,因为它们是为嵌套循环中的每个图像像素调用的:

for y in range (0, height):
   white = 0
   for x in range (0, width):
      if im.getpixel((x,y)) > 200:
         white = white+1
   if white <= minimalGridWidth:
      minimalGridWidth = white

通过用图像范围的操作替换嵌套循环,可以修复上述代码

np_im = np.array(im)
white_per_row = np.sum(np_im > 200, axis=1)
minimalGridWidth = np.min(white_per_row)

替换此单一操作可将总执行时间减少5644毫秒或~32%

enter image description here

相关问题 更多 >