To avoid rotation in a similar task, I repeat for each pixel in a RotatedRect with this function:
double filling(Mat& img, RotatedRect& rect){ double non_zero = 0; double total = 0; Point2f rect_points[4]; rect.points( rect_points ); for(Point2f i=rect_points[0];norm(i-rect_points[1])>1;i+=(rect_points[1]-i)/norm((rect_points[1]-i))){ Point2f destination = i+rect_points[2]-rect_points[1]; for(Point2f j=i;norm(j-destination)>1;j+=(destination-j)/norm((destination-j))){ if(img.at<uchar>(j) != 0){ non_zero+=1; } total+=1; } } return non_zero/total; }
It looks like regular iteration over a rectangle, but at each step we add the 1px vector to the current point in the direction of the destination.
This loop does NOT iterate over all the points and skips a few pixels, but that was normal for my task.
UPD: It is much better to use LineIterator to iterate:
Point2f rect_points[4]; rect.points(rect_points); Point2f x_start = rect_points[0]; Point2f x_end = rect_points[1]; Point2f y_direction = rect_points[3] - rect_points[0]; LineIterator x = LineIterator(frame, x_start, x_end, 4); for(int i = 0; i < x.count; ++i, ++x){ LineIterator y = LineIterator(frame, x.pos(), x.pos() + y_direction, 4); for(int j=0; j < y_count; j++, ++y){ Vec4b pixel = frame.at<Vec4b>(y.pos); } }
Pavlo Razumovskyi
source share