在Colab中使用YOLOv4进行车牌检测时运行convert_annotations.py脚本出现ValueError问题求助
Fixing ValueError: could not convert string to float: 'registration' in YOLOv4 Annotation Conversion
Hey there, let's break down this error and fix it step by step!
What's Causing the Error?
This error happens because your class name "Vehicle registration plate" contains spaces, and your code's logic assumes class names are single words. Here's the play-by-play:
- When your code runs
labels = line.split()on a raw annotation line, it splits the multi-word class name into 3 separate elements:['Vehicle', 'registration', 'plate', 'xmin', 'ymin', 'xmax', 'ymax'] - Your code tries to convert
labels[1](which is "registration") to a float for coordinates—this obviously fails, since it's a string, not a number. - On top of that, your class name replacement logic (
line.replace(class_type, ...)) doesn't work for multi-word class names: it can't match the full "Vehicle registration plate" string in the split line, so the replacement never happens.
How to Fix It
We need to adjust the code to properly handle multi-word class names and extract coordinates correctly. Here are two solid solutions:
Solution 1: Rewrite Annotation Line Processing (Recommended)
Replace the annotation processing loop in your script with this code, which explicitly separates multi-word class names from coordinate values:
for line in f: # Split the line and separate class name from coordinates parts = line.strip().split() # Find the first index where a number starts (end of class name) first_num_idx = 0 while first_num_idx < len(parts) and not parts[first_num_idx].replace('.', '', 1).isdigit(): first_num_idx += 1 # Reconstruct the full multi-word class name class_name = ' '.join(parts[:first_num_idx]) # Extract the coordinate values coords_parts = parts[first_num_idx:first_num_idx+4] coords = np.asarray([float(coord) for coord in coords_parts]) # Get the class ID from your classes dictionary class_id = classes.get(class_name, 0) # Use 0 as fallback if class isn't found # Convert coordinates to YOLO's normalized format coords = convert(filename_str, coords) # Build the new YOLO-style annotation line newline = f"{class_id} {coords[0]} {coords[1]} {coords[2]} {coords[3]}\n" annotations.append(newline)
Solution 2: Standardize Class Names to Be Space-Free (Quick Fix)
If you prefer not to rewrite the logic, you can:
- Update
classes.txtto use a space-free class name likeVehicle_registration_plate - Batch-replace all instances of "Vehicle registration plate" in your annotation files with
Vehicle_registration_plate
This will make your original split/replace logic work, but it's less flexible if you add other multi-word classes later.
Extra Tips to Avoid Future Issues
- Check Class Name Consistency: Make sure the class name in
classes.txtmatches exactly what's in your annotation files (including spaces, capitalization, etc.). - Avoid Directory Chaos: Your
convertfunction usesos.chdir()which can lead to path errors. Replace it with absolute paths instead:
This removes the need fordef convert(filename_str, coords): # Use absolute path to load the image image_path = os.path.join(ROOT_DIR, "OID", "Dataset", DIR, CLASS_DIR, f"{filename_str}.jpg") image = cv2.imread(image_path) # Rest of your coordinate conversion logic stays the same coords[2] -= coords[0] coords[3] -= coords[1] x_diff = int(coords[2]/2) y_diff = int(coords[3]/2) coords[0] = coords[0]+x_diff coords[1] = coords[1]+y_diff coords[0] /= int(image.shape[1]) coords[1] /= int(image.shape[0]) coords[2] /= int(image.shape[1]) coords[3] /= int(image.shape[0]) return coordsos.chdir("..")andos.chdir("Label")in the function.
内容的提问来源于stack exchange,提问作者brian grey
相关产品推荐
相关产品推荐

