我将图像旋转 x(45 度)角度,但旋转后的图像中出现了一些黑点。
如何避免那些黑点!!
我使用的逻辑如下
double sinx = sin((M_PI/4)*(180.0/M_PI)); //45 degrees
double cosx = cos((M_PI/4)*(180.0/M_PI));
xCenter = height/2; // Rotate image by its center.
yCenter = width/2;
for(x=0; x<height; x++) {
for(y=0; y<width; y++) {
xt = x-xCenter; yt=y-yCenter;
xRotate = (int) round( ((xt*cosx)-(yt*sinx)) + xCenter );
yRotate = (int) round( ((yt*cosx)+(xt*sinx)) + yCenter );
if( (x >= 0) && (x < height) && (y >= 0) && (y < width) ) {
rotatedImage[xRotate][yRotate] = inputImage[x][y];
}
}
}
不要循环未旋转图像的像素,而是循环旋转图像。这意味着您不会因为将旋转坐标四舍五入到
int
而错过像素。
sin((M_PI/4)*(180.0/M_PI));
不是“45 度”的正弦值。 它是 45 弧度的正弦值。同样的double cosx
建议
double sinx = sin(45.0/180.0*M_PI);
还要考虑
lround()
与 (int) round()
。
此外,
xRotate, yRotate
的范围大约是height, width
的范围的sqrt(2)倍。 从 double
转换时,代码应注意整数溢出。
按照 @Chris Turner 的回答和 @M Oehm
的评论进行迭代下面使用类似 OP 的代码,但随着代码映射 from
inputImage
.,旋转为 -45
#defined SIND(a) (sin((a)/180.0 * M_PI)
#defined COSD(a) (cos((a)/180.0 * M_PI)
double sinx = SIND(-45); // -degrees
double cosx = COSD(-45);
xCenter = height; // Rotate image by its center.
yCenter = width;
for(x=0; x<height; x++) {
xt = x - xCenter;
double xt_cosx = xt*cosx;
double xt_sinx = xt*sinx;
for(y=0; y<width; y++) {
yt = y - yCenter;
long xRotate = lround(xt_cosx - (yt*sinx)) + xCenter;
long yRotate = lround((yt*cosx) + xt_sinx) + yCenter;
if( (xRotate >= 0) && (xRotate < height) && (yRotate >= 0) && (yRotate < width) ) {
rotatedImage[x][y] = inputImage[xRotate][yRotate];
} else {
rotatedImage[x][y] = Default_Pixel;
}
}
}
更改为应用旋转变换的逆矩阵可以帮助您永远不会错过输出中的任何像素。
我的代码供您参考。
void rotate(uint8_t* dst, uint8_t* src, int w, int h, int depth, int theta) {
if (depth != 8) {
printf("Only support 8bits image !\n");
return;
}
memset(dst, 0, sizeof(uint8_t)*w*h);
float phi = theta/180.0*PI;
float T_inv[2][2] = { cos(phi), sin(phi),
-sin(phi), cos(phi)};
int i_;
int j_;
int center_i = round(w/2.0);
int center_j = round(h/2.0);
//v' = Tinv * v
for (int j=0; j<h; j++) {
for (int i=0; i<w; i++) {
i_ = round(T_inv[0][0]*(i-center_i) + T_inv[0][1]*(j-center_j)) + center_i;
j_ = round(T_inv[1][0]*(i-center_i) + T_inv[1][1]*(j-center_j)) + center_j;
if (i_ < 0 || j_ < 0)
continue;
if (i_ >= w)
continue;
if (j_ >= h)
continue;
dst[i+j*w] = src[i_+j_*w];
}
}
return;
}