基于OpenCV与KNN算法的手写数字OCR训练数据扩展及文件覆盖问题
Hey there! Sounds like you’ve built a really solid base with your Python/OpenCV/KNN digit OCR system—nice work getting the core annotation and saving flow working. Let’s squash that annoying overwrite problem so you can keep building up your training dataset without losing existing data.
The Root Cause
Right now, your code is almost certainly using the 'w' (write) mode when opening your text file. This mode clears the entire file before writing new content, which is why each new annotation wipes out what you had before.
The Quick Fix: Use Append Mode
Switch to the 'a' (append) mode instead. This mode will:
- Create the file if it doesn’t exist
- Add new content to the end of the file without touching existing data
Here’s how to adjust your save logic:
Before (Overwrites Data):
# This is what you're probably doing now with open('digit_training_data.txt', 'w') as f: # Write label + flattened image data f.write(f"{user_input_label},{','.join(map(str, flattened_image))}\n")
After (Appends Data):
# Use 'a' instead of 'w' to append with open('digit_training_data.txt', 'a') as f: f.write(f"{user_input_label},{','.join(map(str, flattened_image))}\n")
Bonus: Add a Structured Header (For Cleaner Data)
To make your dataset easier to work with later (when loading for KNN training), add a header row the first time the file is created. This avoids mixing labels with pixel data and makes parsing clearer:
import os data_file_path = 'digit_training_data.txt' # Check if the file doesn't exist yet if not os.path.exists(data_file_path): with open(data_file_path, 'w') as f: # Assuming your flattened images are 28x28 (784 pixels, like MNIST) header = 'label,' + ','.join([f'pixel_{i}' for i in range(784)]) + '\n' f.write(header) # Now append the new annotation with open(data_file_path, 'a') as f: f.write(f"{user_input_label},{','.join(map(str, flattened_image))}\n")
Pro Tip: Use CSV Format for Better Data Structure
Instead of a plain text file, consider using a CSV (Comma Separated Values) file. It’s more standardized, and tools like pandas can load it in one line for training later. The csv module handles edge cases (like if your data accidentally has commas) automatically:
import csv data_file_path = 'digit_training_data.csv' with open(data_file_path, 'a', newline='') as csv_file: writer = csv.writer(csv_file) # Write header if the file is empty if csv_file.tell() == 0: header = ['label'] + [f'pixel_{i}' for i in range(784)] writer.writerow(header) # Write the new annotation as a row writer.writerow([user_input_label] + flattened_image)
Quick Checks to Avoid Headaches Later
- Make sure every flattened image has the same number of pixels (e.g., always resize digits to 28x28 before flattening). KNN will throw errors if feature vectors are inconsistent.
- If you ever need to reset your dataset, just delete the file manually or add a small flag in your script (like a
--resetcommand line argument) to trigger a'w'mode write once.
That should do it—you’ll now be able to keep adding handwritten digit annotations without losing your existing training data!
内容的提问来源于stack exchange,提问作者Michael Helmbrecht

