Converting and reassigning a 90 degree roll with a roll

I need to convert and reassign an equiangular image to another equiangular image with a 90 ° roll.

I did it with Pano2VR .

The problem is that I have to do this programmatically from the server side . Therefore, I cannot use the GUI for this.

First, I focused my research on imagemagick. I tried the Fred ImageMagick scripts but couldn't find anyone to do what I want to do. Moreover, the image processing time looks very long compared to Pano2VR.

I directed my research to OpenCV and libgnomonic . This is currently the most interesting way. This library allows the user to convert projections (equilateral to rectilinear and vice versa) or to make an equal transformation of the mapping . I played with Norama-suite , which contains some scripts for working with the library. For example, I would like to convert a rectilinear image to equirectangular, but the output was only a black background (why? I did not find the answer).

However, this second link may solve my problem. I have this image:

rot-yz-equirectangular.jpg? raw = true

and I want to convert it to this image

equirectangular.jpg? raw = true

Well, I'm not comfortable with C. at all. I think I should use these two files:

But I do not know how to do this. And first of all, I want to understand.

Am I on the right track? What conversion applies to the first image? Is there a way to do this with a python or bash script?

Ok, thanks for your help.


** CHANGE Transpose C in python ** The following code did not work and did not return, but IndexError. However, I tried to catch and pass the exception, and the first right side of the image did not change.

import math from PIL import Image img = Image.open("img1.jpg") img = img.convert('RGB') pixel = img.load() width, height = img.size img2 = img.copy() for y in xrange(height): for x in xrange(width): xx = 2*(y+0.5) / width - 1.0 yy = 2*(y+0.5)/ height - 1.0 lng = math.pi * xx lat = 0.5 * math.pi * yy # NOTE! These axes are transposed because that what the question is about Z = math.cos(lat) * math.cos(lng) # normally X Y = math.cos(lat) * math.sin(lng) # normally Y X = -math.sin(lat) # normally -Z D = math.sqrt(X*X+Y*Y) lat = math.atan2(Z, D) # ? normally lat = math.asin(Z) lng = math.atan2(Y, X) #ix and iy must be integers ix = int((0.5 * lng / math.pi + 0.5) * width - 0.5) iy = int((lat/math.pi + 0.5) * height - 0.5) #not sure of this part to remap the image newpixel = pixel[ix, iy] img2.putpixel([(x+width/4) % width, y], newpixel) #I tries as mentionned in the following code to invert x and y in the two previous lines but the index error out of range comes back img2.show() 
+5
source share
1 answer

Your conversion consists of two steps. The first step is to transform the projection sphere, the second is a 90 ° shaft.

A 90-degree roll of an equiangular image is only a horizontal shift of a quarter of the width of the image. The first transformation is more complicated: you basically want to rotate the sphere so that the north pole is at latitude 0 and longitude 0 (somewhere in the Gulf of Guinea, if you take Earth as a reference).

You can perform this conversion using these steps;

  • Translate the x and y positions of each pixel in longitude, & minus; ? pi & Le; long? ?, and latitude,? / 2? lat? & Pi; / 2. This is a linear transformation.
  • Create the x, y, and z coordinates of the corresponding longitude and latitude on the unit sphere; positive z is the north pole.
  • Rotate these Cartesian coordinates. In your case, you just need to change some dimensions, but it can be a general transformation with any transformation matrix.
  • Calculate the length and latitude of the rotated coordinates.
  • Convert new longitude and latitude to pixel position.

Here's the C code that works. (I know that you noted the question using Python, but the code below is mostly formulas that work similarly in python. You have to take care: the whole number is floating point numbers, except for pixel indices x , y , ix and iy . I would do it in Python, but I have no experience with the Python image library.)

 for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { double xx = 2 * (x + 0.5) / width - 1.0; double yy = 2 * (y + 0.5) / height - 1.0; double lng = pi * xx; double lat = 0.5 * pi * yy; double X, Y, Z; double D; int ix, iy; Z = cos(lat) * cos(lng); // corresponds to original x Y = cos(lat) * sin(lng); // corresponds to original y X = -sin(lat); // corresponds to original z D = sqrt(X*X + Y*Y); // distance in the XY plane lat = atan2(Z, D); lng = atan2(Y, X); ix = (0.5 * lng / pi + 0.5) * width - 0.5; iy = (lat / pi + 0.5) * height - 0.5; dest[y][(x + width / 4) % width] = src[iy][ix]; // width/4 offset ist the 90° roll // % width wraps the longitude } } 

The quality of the resulting image is fine, but not as good as your reference image, especially near the poles. The best woul algorithm averages and aligns color values. The algorithm above only maps one destination pixel to the original pixel.

+3
source

Source: https://habr.com/ru/post/1242406/


All Articles