Aspect ratio of an image resized with Opencv?

Asked

Viewed 1,220 times

1

I have a project where I need to identify objects in an image, currently using the Opencv library in C++. I used the function warpPerspective() Opencv on a 605x141 size image to resize your perspective to a 674x35 size image. In doing so the object of the image was distorted as in the illustration of Example in the image below:inserir a descrição da imagem aqui

Let’s say the width of the object in the first image is 100, for example. How can I identify the new width of the object in the new distorted image? It seems obvious but I tried to use the basic rule of three, using the area and aspect ratio of the two images, but the result is not clicking when I manually compare the width in an image editor.

Note: If this question is not compatible with any forum policy, please let me know so I can try to rewrite it.

EDIT:

I do not know exactly if it will help to solve the problem, but here is the code where I perform the perspective transformation:

void MyClass::TransformPerspec(){

Mat mat = cvCreateMat(3, 3, CV_8UC1);
this->fileira = cvCreateMat(35, 674, CV_8UC1); // matriz de saida da fileira será de tamanho 674x35

// Input Quadilateral or Image plane coordinates
Point2f inputQ[4];
// Output Quadilateral or World plane coordinates
Point2f outputQ[4];

inputQ[0].x = this->X1; inputQ[0].y = this->Y1;
inputQ[1].x = this->X2; inputQ[1].y = this->Y2;
inputQ[2].x = this->X3; inputQ[2].y = this->Y3;
inputQ[3].x = this->X4; inputQ[3].y = this->Y4;

outputQ[0].x = 0 ; outputQ[0].y = 0;
outputQ[1].x = 674;outputQ[1].y = 0;
outputQ[2].x = 0;  outputQ[2].y = 35;
outputQ[3].x = 674;outputQ[3].y = 35;

mat = getPerspectiveTransform(inputQ, outputQ);
warpPerspective(this->imagem_proc, this->fileira, mat, this->fileira.size());

imwrite("Teste.bmp", this->fileira);

}

After perspective transformation I just call this method:

reconheceObject(int largura);

where I use the object width of the first image for recognition, but since the object is distorted after the perspective transform, the 'width' value needs to be recalculated based on the new image. So I initially thought I could use a rule of three to find the new width. But now I know that a possible solution is not so simple.

  • 1

    What is the value returned by the rule of 3, and what is the value being returned "manually" ? The difference is very large ? Note. more like curiosity, I don’t know Opencv.

  • In the resized image, counting manually, the width value is 120. Performing the rule of three by the aspect ratio, I have L = (19,26100)/4,29 = 448. Using the rule of three for the image area, I have: L = (23590100)/85305 = 27,65. The resulting width values are completely different, not even approaching. When I scan the resized image, the width is 120. : / Thank you for responding.

  • You can’t use 3 rule for this, because your operation does not maintain proportion. On the contrary, you are applying a perspective transformation to the image (it is as if you have "laid down" the original image and are looking at the ball from another position).

  • I honestly don’t know the answer, but I suppose you can use the formula that appears in the documentation with the same transformation matrix that you applied to the image. It should be possible to "map" the coordinates of the corners of the ball from the original image to the new image, and then just measure the dimensions between these new coordinates.

  • On the other hand, depending on how the background is and the object (the ball) of the image, it may be simply easier for you to segment it again (or only) in the transformed image. I would suggest that you edit the question to post a code example, a [mcve] if possible. It makes it easy for someone to be interested in helping you.

  • The perspective transformation I am using only to be able to make the image close to a standard image for diagonal objects. The ball lying would actually be its sides that warped sideways, because the image was actually flattened. I will organize my code and post on the question to facilitate understanding of my problem. Thank you.

  • 1

    "The perspective transformation I’m using just so I can make the image close to a standard image for diagonal objects." This is the kind of thing you do in art and design, not in the computational use of images. If you change the image just so it "looks cooler", you only make it harder to target.

  • The perspective transformation is to fix the rotational angle of the object I’m identifying. Imagine that I have an image intera with several objects lined diagonally. The perspective transformation is to correct this difference in angulation so that I can identify objects in a linear way in the image. When I tidy up the perspective, I record the rotated image on the 674x35. The problem is q need to identify the width of the object in the transformed image q is where I’m having problems. Because the new image is modifying the representation of the object.

  • Soon I will edit my post with the perspective code. To try to clarify better the problem.

  • 1

    Yes, I understand Yuri. I just don’t understand why you think you need to align objects differently so you can identify them. Anyway, that’s another problem. Your original question is how to calculate the dimension of an object after a warp operation. My tip was given (I just didn’t answer because I’m not sure if it works). Now, whether this will all be useful or not is another problem. I just tried to give the additional hint that maybe you are complicating something that is not necessary to be complicated. Anyway, that’s it. Good luck.

  • 1

    Thank you @Luizvieira, I was reluctant to post the code because the project is huge at the moment, and I thought it would be more a matter of logic that I couldn’t see. I will take a look at the opencv documentation to find some alternatives. Thank you!

  • Does the Opencv library have methods(functions) that return the parameters (height, width, etc) of the image directly ? Do we really need to calculate the parameters of the modified image ? Suddenly it’s just a matter of properly using Opencv’s own resources.

Show 7 more comments

2 answers

1

Hey, I think you need the job resize(src,dst,size), where src is your original image and dst is a new image variable that you will create and size is the final image size that you can declare as such: Size(100,100).

  • Hi, welcome to SOPT. I know you don’t have enough reputation to comment yet, but the answer fields should only be used to give a direct answer to the question. Suggestions and questions should be given in comments.

1

To maintain the proportions of the original image without any distortions you can only choose arbitrarily the size of one of the new dimensions, the other dimension will increase or decrease according to the change in the chosen dimension, So if your image has 100 height and you want to increase it to 140 (40% growth), your new width should be 40% larger. This is valid for the choice of both dimensions. The following code snippet gives an idea of how to solve.

    double novaLargura = antigaLargura * novaAltura / antigaAltura;
    resize(img, img, Size(novaLargura, novaAltura));

Browser other questions tagged

You are not signed in. Login or sign up in order to post.