numArEx.txt文件持续加载异常求助:图像识别代码问题排查
Hey there, let's work through your image recognition code problems step by step—there are a few key issues causing your numArEx.txt loading troubles and the overflow-related confusion.
1. Why numArEx.txt Isn't Working (Or Has No Data)
First big catch: you never call the createExamples() function in your code! This function is supposed to generate the numArEx.txt file with your training image data. Right now, when you run whatNumIsThis(), you're trying to read a file that either doesn't exist, is empty, or has garbage data—this is why it seems stuck loading.
Fix this immediately by adding a call to createExamples() before your test function:
createExamples() # Generate the training data file first whatNumIsThis('images/teste.jpg')
Also, when reading the file, trailing empty lines can cause errors in your loop. Clean up the loaded data to skip blank entries:
loadExamps = open('numArEx.txt','r').read().split('\n') loadExamps = [line for line in loadExamps if line.strip()] # Remove empty lines
2. The np.seterr(over='ignore') Problem (And Real Root Cause)
Your hunch about this line is right—but not for the reason you think.
When you load an image with PIL, the resulting numpy array uses uint8 type (values 0-255). In your threshold function, you're doing arithmetic directly on these uint8 values. For example, summing three 255s gives 765, which is way beyond the uint8 limit of 255. This causes an integer overflow, and np.seterr(over='ignore') just hides the warning instead of fixing the problem. The result? Your average color calculations are completely wrong (765 wraps around to 0 in uint8), leading to garbage data in numArEx.txt.
Fix the Overflow:
Convert the image array to a larger integer type (like int32) before calculations to avoid overflow, then convert back when done:
def threshold(imageArray): # Convert to int32 to prevent overflow during sum calculations imageArray = imageArray.astype(np.int32) balanceAr = [] newAr = imageArray.copy() # Work on a copy to avoid modifying the original array for eachRow in imageArray: for eachPix in eachRow: avgNum = sum(eachPix[:3]) / 3 # Sum is simpler and clearer than reduce here balanceAr.append(avgNum) balance = sum(balanceAr) / len(balanceAr) for eachRow in newAr: for eachPix in eachRow: if sum(eachPix[:3]) / 3 > balance: eachPix[:3] = [255, 255, 255] else: eachPix[:3] = [0, 0, 0] # Convert back to uint8 for proper image storage return newAr.astype(np.uint8)
3. Other Quick Fixes to Avoid Headaches
- File Duplication: In
createExamples(), you opennumArEx.txtin append mode ('a'). Run this multiple times and you'll duplicate training data. Use write mode ('w') instead to overwrite old data each time:numberArrayExamples = open('numArEx.txt', 'w') - Simplify Image Opening: You don't need
open(imgFilePath,'rb')insideImage.open()—just useImage.open(imgFilePath)directly. - Safe Counter Lookup: In
whatNumIsThis(), printingx[0]will throw aKeyErrorif 0 isn't in your matches. Usemost_common()to get the top match safely:print(matchedAr) x = Counter(matchedAr) print(x) if x: most_likely_num = x.most_common(1)[0][0] print(f"Most likely number: {most_likely_num}") else: print("No matches found—check your training data or test image.")
4. Final Notes
After applying these fixes, your code should generate a valid numArEx.txt file with correct 0-255 RGB values, load it without issues, and perform much better at recognizing your test image. The overflow warning you saw when removing np.seterr(over='ignore') was actually a helpful clue pointing to the real problem with uint8 arithmetic!
内容的提问来源于stack exchange,提问作者Lucas Diehl

