使用findHomography和warpPerspective时车牌图像旋转异常问题排查
Hey there! Let's figure out why your warped license plate is rotating 90 degrees—this is almost always an issue with point ordering between your source (plate_polygons) and target (real_plate_polygons) points for the homography transform.
The Root Cause
cv::findHomography relies on strict, one-to-one correspondence between your source polygon points and target polygon points. If the order (clockwise/counter-clockwise) or the mapping of individual points doesn't match, the transform will twist/rotate the output instead of aligning it correctly.
Looking at your code:
vector< cv::Point> real_plate_polygons; real_plate_polygons = { cv::Point(PLATE_WIDTH, PLATE_HEIGHT), // 右下 cv::Point(0, PLATE_HEIGHT), // 左下 cv::Point(0, 0), // 左上 cv::Point(PLATE_WIDTH, 0) // 右上 };
Your target points are ordered bottom-right → bottom-left → top-left → top-right. If your plate_polygons are ordered in a different pattern (e.g., top-left → top-right → bottom-right → bottom-left, a standard clockwise order), this mismatch will cause the 90-degree rotation.
Step-by-Step Fixes
Standardize Point Ordering
Choose a consistent order (e.g., clockwise starting from the top-left corner) for both source and target points. For a normal horizontal license plate, your target points should look like this:vector<cv::Point> real_plate_polygons = { cv::Point(0, 0), // Top-left cv::Point(PLATE_WIDTH, 0), // Top-right cv::Point(PLATE_WIDTH, PLATE_HEIGHT), // Bottom-right cv::Point(0, PLATE_HEIGHT) // Bottom-left };Ensure
plate_polygonsMatches the Order
Verify that the four points inplate_polygonsfollow the same clockwise/counter-clockwise order as your target points. If yourplate_polygonscome directly from contour detection, they might be unordered—you'll need to sort them.Here's a quick way to sort polygon points clockwise around their center:
// Calculate the center of the plate polygon cv::Point2f center(0, 0); for (const auto& p : plate_polygons) { center.x += p.x; center.y += p.y; } center.x /= 4; center.y /= 4; // Sort points clockwise based on angle relative to center sort(plate_polygons.begin(), plate_polygons.end(), [&](const cv::Point& a, const cv::Point& b) { float angleA = atan2(a.y - center.y, a.x - center.x); float angleB = atan2(b.y - center.y, b.x - center.x); return angleA < angleB; });Double-Check Dimensions
Make surePLATE_WIDTHis larger thanPLATE_HEIGHT(since standard license plates are wider than they are tall). If you accidentally swapped these values, it could also lead to a rotated or squashed output.
Quick Verification
Before running the transform, draw the ordered plate_polygons on your source image using cv::polylines—this will let you confirm the points are arranged in the expected clockwise/counter-clockwise order.
Once you align the point order between source and target, the warpPerspective output should be correctly oriented, just like your other working examples!
内容的提问来源于stack exchange,提问作者Jose Tomas

