Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/tensorflow/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ EasyBMP任意角度旋转图像_C++_Bmp - Fatal编程技术网

C++ EasyBMP任意角度旋转图像

C++ EasyBMP任意角度旋转图像,c++,bmp,C++,Bmp,我正在尝试使用EasyBMP旋转bmp图像。当角度介于0和90或270和360之间时,旋转很好。但在180和270之间时,边界矩形被拉伸,对于90和180之间的角度,我得到了分割错误。我相信这个问题是由 int width = image.TellWidth(); int height = image.TellHeight(); float sine= sin(angle); float cosine=cos(angle); float x1=-height*sine; float y1=h

我正在尝试使用EasyBMP旋转bmp图像。当角度介于0和90或270和360之间时,旋转很好。但在180和270之间时,边界矩形被拉伸,对于90和180之间的角度,我得到了分割错误。我相信这个问题是由

int width = image.TellWidth();
int height = image.TellHeight();

float sine= sin(angle);
float cosine=cos(angle);

float x1=-height*sine;
float y1=height*cosine;
float x2=width*cosine-height*sine;
float y2=height*cosine+width*sine;
float x3=width*cosine;
float y3=width*sine;

float minx=min(0,min(x1,min(x2,x3)));
float miny=min(0,min(y1,min(y2,y3)));
float maxx=max(x1,max(x2,x3));
float maxy=max(y1,max(y2,y3));

int outWidth;
int outHeight;


     outWidth=(int)ceil(fabs(maxx)-minx);
     outHeight=(int)ceil(fabs(maxy)-miny);
output.SetSize(outHeight,outWidth);

for(int x=0; x<outWidth; x++)
{
    for(int y=0; y<outHeight; y++)
    {
        int srcX=(int)((x+minx)*cosine+(y+miny)*sine); 
            int srcY=(int)((y+miny)*cosine-(x+minx)*sine);
        if(srcX>=0 &&srcX<width && srcY>=0 && srcY<height)
        {
            output.SetPixel(x,y,image.GetPixel(srcX,srcY));
        }
    }
}
int-width=image.TellWidth();
int height=image.TellHeight();
浮动正弦=正弦(角度);
浮动余弦=余弦(角);
浮动x1=-高度*正弦;
浮动y1=高度*余弦;
浮动x2=宽度*余弦高度*正弦;
浮动y2=高度*余弦+宽度*正弦;
浮点x3=宽度*余弦;
浮动y3=宽度*正弦;
float minx=min(0,min(x1,min(x2,x3));
float miny=min(0,min(y1,min(y2,y3));
float maxx=max(x1,max(x2,x3));
浮点最大值=最大值(y1,最大值(y2,y3));
外展;
内部高度;
外宽=(int)cel(fabs(maxx)-minx);
高度=(内部)天花板(最大尺寸)-最小尺寸);
输出.SetSize(外高、外宽);

对于(int x=0;x我是这样解决的。TL;DR:旋转变换是围绕0,0进行的,因此如果图像坐标设置为左下角的0,0,则需要首先将图像平移到0,0的中心。此外,正弦波和余弦波期望的是弧度,而不是度,所以请记住首先进行转换

漫长的道路: 我首先创建了一个简单的程序,可以轻松地验证答案,找出哪里出了问题

我注意到的第一件事是90.0f不会产生任何输出。这看起来很奇怪,所以我开始使用“输出图像大小”printf,并意识到输出高度被计算为-87。显然这是不对的,让我们看看为什么会发生这种情况

上升一点,
outHeight=(int)ceil(fabs(maxy)-miny)
那么,让我们计算一下,在减去maxy和miny时,我们的输出高度是负的。maxy似乎是-0.896…miny是88.503…但是,在减去miny之前取maxy的绝对值,这意味着我们的输出高度是0.896-88.503。哇,这不好!让我们先做减法,然后取ab绝对值

以宽度和高度重新编译: 外径=(整数)ceil(晶圆厂(最大最小值)); 高度=(内部)天花板(最大尺寸)

获取更好的值。现在outWidth和outHeight分别为2和90。这有了很大的改进,但高度应该为100。我们将在稍后讨论

为了找出数学错误的地方,我重新组织了术语:x与x,y与y。接下来,我调整了间距并添加了括号,以使其更具可读性并确保操作顺序(当然比试图查看OoO表要好;)。很明显,你正在打破旋转矩阵乘法,我将给你的变量命名为比x1、x2等更直观的名称。从现在开始,x1是topLeftTransformedX,x2是topRightTransformedX,x3将作为bottomLeftTransformedX存在(始终为0),x4将是bottomRightTransformedX,与Y相同。更长时间,但是更容易知道你在处理什么

用这个,在这一点上,我看到了和你一样的事情。。。然后我想起了一些东西,基于从这个更干净的代码中看到的数字(与您的数学相同,但更容易调试)

突然,我对X的计算结果如下: //x=x cos-y sin 浮点topLeftTransformedX=(-midX*余弦)-(midY*正弦); 浮点topRightTransformedX=(midX*余弦)-(midY*正弦); float bottomLeftTransformedX=(-midX*余弦)-(-midY*正弦); float bottomRightTransformedX=(midX*余弦)-(-midY*正弦)

旋转矩阵围绕中心点旋转。您必须平移图像,使其围绕图像中心进行适当旋转

然后,当我试图找出为什么这会给出它的值时,我想起了另一件事——角度需要以弧度为单位

突然间,几乎所有的工作。还有一些事情要做,但这应该能让你达到95%甚至更多。希望有帮助

// bmprotate.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <math.h>

#define min(x,y) x < y ? x : y
#define max(x,y) x > y ? x : y
#define PI 3.14159

void rotate(int width, int height, float angleInDeg)
{
    float angle = angleInDeg * (PI/180.0f);
    float midX = ((float)width) / 2.0f;
    float midY = ((float)height) / 2.0f;

    float sine = sin(angle);
    float cosine = cos(angle);

    // x = x cos - y sin
    float topLeftTransformedX = (-midX * cosine) - (midY * sine);
    float topRightTransformedX = (midX * cosine) - (midY * sine);
    float bottomLeftTransformedX  = (-midX * cosine) - (-midY * sine);
    float bottomRightTransformedX = (midX * cosine) - (-midY * sine);

    float minx = min( topLeftTransformedX, min(topRightTransformedX, min(bottomLeftTransformedX, bottomRightTransformedX)) );
    float maxx = max( topLeftTransformedX, max(topRightTransformedX, max(bottomLeftTransformedX, bottomRightTransformedX)) );

    // y = x sin + y cos
    float topLeftTransformedY = (-midX * sine) + (midY * cosine);
    float topRightTransformedY = (midX * sine) + (midY * cosine);
    float bottomLeftTransformedY  = (-midX * sine) + (-midY * cosine);
    float bottomRightTransformedY = (midX * sine) + (-midY * cosine);



    float miny = min( topLeftTransformedY, min(topRightTransformedY, min(bottomLeftTransformedY, bottomRightTransformedY)) );
    float maxy = max( topLeftTransformedY, max(topRightTransformedY, max(bottomLeftTransformedY, bottomRightTransformedY)) );

    int outWidth;
    int outHeight;

    printf("(%f,%f) , (%f,%f) , (%f,%f) , (%f,%f)\n", 
        topLeftTransformedX, topLeftTransformedY, 
        topRightTransformedX, topRightTransformedY, 
        bottomLeftTransformedX, bottomLeftTransformedY, 
        bottomRightTransformedX, bottomRightTransformedY);


    outWidth = (int) ceil( fabs(maxx) + fabs(minx));
    outHeight = (int) ceil( fabs(maxy) + fabs(miny) );

    printf("output image size: (%d,%d)\n",outWidth,outHeight);
    for(int x=0; x<outWidth; x++)
    {
        for(int y=0; y<outHeight; y++)
        {
            int srcX=(int)((x+minx)*cosine+(y+miny)*sine); 
            int srcY=(int)((y+miny)*cosine-(x+minx)*sine);

            if(srcX >=0 && srcX < width && srcY >= 0 && srcY < height)
            {
                printf("(x,y) = (%d,%d)\n",srcX, srcY);
            }
        }
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    rotate(100,2,90.0f);
    for (int i = 0; i < 360; i++)
    {

    }
    return 0;
}
//bmprotate.cpp:定义控制台应用程序的入口点。
//
#包括“stdafx.h”
#包括
#定义最小(x,y)xy?x:y
#定义PI 3.14159
空心旋转(内部宽度、内部高度、浮动角度)
{
浮动角度=角度指数*(PI/180.0f);
浮动中点=((浮动)宽度)/2.0f;
浮动中间高度=((浮动)高度)/2.0f;
浮动正弦=正弦(角度);
浮动余弦=余弦(角);
//x=x cos-y sin
浮点topLeftTransformedX=(-midX*余弦)-(midY*正弦);
浮点topRightTransformedX=(midX*余弦)-(midY*正弦);
float bottomLeftTransformedX=(-midX*余弦)-(-midY*正弦);
float bottomRightTransformedX=(midX*余弦)-(-midY*正弦);
float minx=min(topLeftTransformedX,min(topRightTransformedX,min(bottomLeftTransformedX,bottomRightTransformedX));
float maxx=max(topLeftTransformedX,max(topRightTransformedX,max(bottomLeftTransformedX,bottomRightTransformedX));
//y=x正弦+y余弦
浮点topLeftTransformedY=(-midX*正弦)+(midY*余弦);
浮点topRightTransformedY=(midX*正弦)+(midY*余弦);
float bottomLeftTransformedY=(-midX*正弦)+(-midY*余弦);
float bottomRightTransformedY=(midX*正弦)+(-midY*余弦);
float miny=min(topLeftTransformedY,min(topRightTransformedY,min(bottomLeftTransformedY,bottomRightTransformedY));
浮点最大值=最大值(topLeftTransformedY,max(topRightTransformedY,max(bottomLeftTransformedY,bottomRightTransformedY));
外展;
内部高度;
printf((%f,%f),(%f,%f),(%f,%f),(%f,%f),(%f,%f)\n“,
topLeftTransformedX,topLeftTransformedY,
topRightTransformedX,topRightTransformedY,
bottomLeftTransformedX,bottomLeftTransformedY,
bottomRightTransformedX、bottomRightTransformedY);
外径=(int)ceil(晶圆厂(maxx)+晶圆厂(minx));
身高=(内部)天花板(最大尺寸)+最小尺寸);
printf(“输出图像大小:(%d,%d)\n)”,向外宽度,向外高度);
对于(int x=0;x=0&&srcY<