Last active
October 15, 2024 22:40
-
-
Save nvs-abhilash/75a3920980fe32ffd4754bc205362125 to your computer and use it in GitHub Desktop.
Helper function to resize and rotate contours using OpenCV
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import cv2 | |
import numpy as np | |
def cart2pol(x, y): | |
theta = np.arctan2(y, x) | |
rho = np.hypot(x, y) | |
return theta, rho | |
def pol2cart(theta, rho): | |
x = rho * np.cos(theta) | |
y = rho * np.sin(theta) | |
return x, y | |
def rotate_contour(cnt, angle): | |
M = cv2.moments(cnt) | |
cx = int(M['m10']/M['m00']) | |
cy = int(M['m01']/M['m00']) | |
cnt_norm = cnt - [cx, cy] | |
coordinates = cnt_norm[:, 0, :] | |
xs, ys = coordinates[:, 0], coordinates[:, 1] | |
thetas, rhos = cart2pol(xs, ys) | |
thetas = np.rad2deg(thetas) | |
thetas = (thetas + angle) % 360 | |
thetas = np.deg2rad(thetas) | |
xs, ys = pol2cart(thetas, rhos) | |
cnt_norm[:, 0, 0] = xs | |
cnt_norm[:, 0, 1] = ys | |
cnt_rotated = cnt_norm + [cx, cy] | |
cnt_rotated = cnt_rotated.astype(np.int32) | |
return cnt_rotated |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import cv2 | |
import numpy as np | |
def scale_contour(cnt, scale): | |
M = cv2.moments(cnt) | |
cx = int(M['m10']/M['m00']) | |
cy = int(M['m01']/M['m00']) | |
cnt_norm = cnt - [cx, cy] | |
cnt_scaled = cnt_norm * scale | |
cnt_scaled = cnt_scaled + [cx, cy] | |
cnt_scaled = cnt_scaled.astype(np.int32) | |
return cnt_scaled |
Thank you, I using your code to align contour for 2D packing problem
I translate your code to C++
#include <algorithm>
#include <cmath>
#include <array>
#include <math.h>
using namespace cv;
using namespace std;
array<double,2> cart2pol(int &x,int &y){
double theta=atan2(y,x);
double rho=hypot(x,y);
return array<double,2>{{theta,rho}};
}
Point pol2cart(double &theta,double &rho)
{
int x=ceil(rho*cos(theta));
int y=ceil(rho*sin(theta));
return Point(x,y);
}
vector<Point> rotate_contour(vector<Point> &cnt,float &angle){
Moments M=moments(cnt);
int cx= int(M.m10/M.m00);
int cy = int(M.m01/M.m00);
vector<Point>cnt_rot;
cnt_rot.reserve(cnt.size());
Point pcenter(cx,cy);
for (Point icnt : cnt)
{
Point tmp(icnt-pcenter);
array<double,2> thetasRho=cart2pol(tmp.x,tmp.y);
thetasRho[0]=thetasRho[0]+angle*M_PI/180;//no rounded to 360 (2*PI)
cnt_rot.push_back(pol2cart(thetasRho[0],thetasRho[1])+pcenter);
}
return (cnt_rot);
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you for all good guide for rotating countours with openCV. Want to ask you about subtracting ( normalizing ) countour pixel coordinates. I did not get why exactly you did that, can you explain ?