簡體   English   中英

AttributeError:'numpy.ndarray'對象沒有屬性'convert'和IndexError:列表索引超出范圍的錯誤

[英]AttributeError: 'numpy.ndarray' object has no attribute 'convert' and error of IndexError: list index out of range

屬性錯誤可能早些時候發布了,但是在我找到解決方案的情況下,我又遇到了另一個錯誤,指出我的列表索引超出范圍。 我是Python的初學者,致力於破解圖片驗證碼。 我已經使用了此處提供的代碼- 如何從驗證碼中完全刪除行

基於此,我添加了幾行來運行它

lineRemoval.py

from PIL import Image,ImageFilter
from scipy.misc import toimage
from operator import itemgetter
from skimage import measure
import numpy as np
import copy
import heapq
import cv2
import matplotlib.pyplot as plt
from scipy.ndimage.filters import median_filter


#----------------------------------------------------------------

class preprocessing:
    def pre_proc_image(self,img):
        #img_removed_noise=self.apply_median_filter(img)
        img_removed_noise=self.remove_noise(img)
        p1,p2,LL=self.get_line_position(img_removed_noise)
        img=self.remove_line(p1,p2,LL,img_removed_noise)
        img=median_filter(np.asarray(img),1)
        return img

    def remove_noise(self,img):
        img_gray=img.convert('L')
        w,h=img_gray.size
        max_color=np.asarray(img_gray).max()
        pix_access_img=img_gray.load()
        row_img=list(map(lambda x:255 if x in range(max_color-15,max_color+1) else 0,np.asarray(img_gray.getdata())))
        img=np.reshape(row_img,[h,w])
        return img

    def apply_median_filter(self,img):
        img_gray=img.convert('L')
        img_gray=cv2.medianBlur(np.asarray(img_gray),3)
        img_bw=(img_gray>np.mean(img_gray))*255
        return img_bw

    def eliminate_zeros(self,vector):
        return [(dex,v) for (dex,v) in enumerate(vector) if v!=0 ]

    def get_line_position(self,img):
        sumx=img.sum(axis=0)
        list_without_zeros=self.eliminate_zeros(sumx)
        min1,min2=heapq.nsmallest(2,list_without_zeros,key=itemgetter(1))
        l=[dex for [dex,val] in enumerate(sumx) if val==min1[1] or val==min2[1]]
        mindex=[l[0],l[len(l)-1]]
        cols=img[:,mindex[:]]
        col1=cols[:,0]
        col2=cols[:,1]
        col1_without_0=self.eliminate_zeros(col1)
        col2_without_0=self.eliminate_zeros(col2)
        line_length=len(col1_without_0)
        dex1=col1_without_0[round(len(col1_without_0)/2)][0]
        dex2=col2_without_0[round(len(col2_without_0)/2)][0]
        p1=[dex1,mindex[0]]
        p2=[dex2,mindex[1]]
        return p1,p2,line_length

    def remove_line(self,p1,p2,LL,img):
        m=(p2[0]-p1[0])/(p2[1]-p1[1]) if p2[1]!=p1[1] else np.inf
        w,h=len(img),len(img[0])
        x=list(range(h))
        y=list(map(lambda z : int(np.round(p1[0]+m*(z-p1[1]))),x))
        img_removed_line=list(img)
        for dex in range(h):
            i,j=y[dex],x[dex]
            i=int(i)
            j=int(j)
            rlist=[]
            while i>=0:
                f1=i
                if img_removed_line[i][j]==0 and img_removed_line[i-1][j]==0:
                    break
                rlist.append(i)
                i=i-1

            i,j=y[dex],x[dex]
            i=int(i)
            j=int(j)
            while True:
                f2=i
                if img_removed_line[i][j]==0 and img_removed_line[i+1][j]==0:
                    break
                rlist.append(i)
                i=i+1
            if np.abs(f2-f1) in [LL+1,LL,LL-1]:
                rlist=list(set(rlist))
                for k in rlist:
                    img_removed_line[k][j]=0

        return img_removed_line

if __name__ == '__main__':
    img = cv2.imread("captcha.png")
    p = preprocessing()
    imgNew = p.pre_proc_image(img)
    cv2.imshow("Image", imgNew)
    cv2.waitKey(0)

最初嘗試上述代碼時,我得到了錯誤

Traceback (most recent call last):
  File "lineRemoval.py", line 98, in <module>
    imgNew = p.pre_proc_image(img)
  File "lineRemoval.py", line 18, in pre_proc_image
    img_removed_noise=self.remove_noise(img)
  File "lineRemoval.py", line 25, in remove_noise
    img_gray=img.convert('L')
AttributeError: 'numpy.ndarray' object has no attribute 'convert'

我通過將主要功能更改為此來搜索並找到了解決方案

if __name__ == '__main__':
    image = cv2.imread("captcha.png")
    img = Image.fromarray(image)
    p = preprocessing()
    imgNew = p.pre_proc_image(img)
    cv2.imshow("Image", imgNew)
    cv2.waitKey(0)

但是之后我的數組超出索引

Traceback (most recent call last):
  File "lineRemoval.py", line 98, in <module>
    imgNew = p.pre_proc_image(img)
  File "lineRemoval.py", line 20, in pre_proc_image
    img=self.remove_line(p1,p2,LL,img_removed_noise)
  File "lineRemoval.py", line 83, in remove_line
    if img_removed_line[i][j]==0 and img_removed_line[i+1][j]==0:
IndexError: list index out of range

無法確定錯誤的位置,是否需要更改while條件,或者是先前的更改導致了錯誤,還是其他原因。

更新資料

我已經更改了while循環的條件,但是對於i> = 0的初始while循環條件也是如此

lineRemoval.py

while i>=0:
    f1=i
        if img_removed_line[i][j]==0 and img_removed_line[i-1][j]==0:
            break
        rlist.append(i)
        i=i-1
i,j=y[dex],x[dex]
i=int(i)
j=int(j)
while i<len(img_removed_line)-1:
    f2=i
        if img_removed_line[i][j]==0 and img_removed_line[i+1][j]==0:
            break
        rlist.append(i)
        i=i+1

顯示的錯誤

Traceback (most recent call last):
  File "lineRemoval.py", line 98, in <module>
    imgNew = p.pre_proc_image(img)
  File "lineRemoval.py", line 20, in pre_proc_image
    img=self.remove_line(p1,p2,LL,img_removed_noise)
  File "lineRemoval.py", line 73, in remove_line
    if img_removed_line[i][j]==0 and img_removed_line[i-1][j]==0:
IndexError: list index out of range

用以下代碼替換函數removed line中的第二個while循環:

while i<len(img_remmoved_line)-1:
    f2=i
    if img_removed_line[i][j]==0 and img_removed_line[i+1][j]==0:
        break
    rlist.append(i)
    i=i+1

您在每次迭代中都增加i ,但有時會打破列表的索引限制。 如果i的值大於該列表的索引限制,則此條件可保護循環的迭代。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM