简体   繁体   中英

2d matrix to image of a cone

I have a 2D numpy matrix of size 512x256. I can easily convert it to an image using PIL, or scipy, etc. but that gives me the shape of a rectangle of size 512x256, obviously. I am wondering if I can do something to make this matrix take shape of a cone like the figure attached? 在此输入图像描述

How I am thinking about it is that the first column of the matrix would be the left most line of the cone and the next column of the matrix would be a little right to that line, and so on. Since the angle between the two extremes is 45 degrees and I have 256 columns, that would be mean that each line gets an increment of (45/256) degree angle? These are just some rough thoughts but I wanted to learn from the community if they have any ideas about how should I proceed with this? I am envisioning a black square main image and this cone in the middle of it. Any ideas/thoughts?

Here is a quick & dirty solution that maps polar coordinates in the result image to rectangular coordinates in the original image and uses interp2d on each channel of the original image:

import numpy as np
from scipy import misc
from scipy.interpolate import interp2d
from math import pi, atan2, hypot

inputImagePath = 'wherever/whateverYouWantToInterpolate.jpg'
resultWidth = 800
resultHeight = 600
centerX = resultWidth / 2
centerY = - 50.0
maxAngle =  45.0 / 2 / 180 * pi
minAngle = -maxAngle
minRadius = 100.0
maxRadius = 600.0

inputImage = misc.imread(inputImagePath)
h,w,chn = inputImage.shape
print(f"h = {h} w = {w} chn = {chn}")
channels = [inputImage[:,:,i] for i in range(3)]
interpolated = [interp2d(range(w), range(h), c) for c in channels]
resultImage = np.zeros([resultHeight, resultWidth, 3], dtype = np.uint8)

for c in range(resultWidth):
  for r in range(resultHeight):
    dx = c - centerX
    dy = r - centerY
    angle = atan2(dx, dy) # yes, dx, dy in this case!
    if angle < maxAngle and angle > minAngle:
      origCol = (angle - minAngle) / (maxAngle - minAngle) * w
      radius = hypot(dx, dy)
      if radius > minRadius and radius < maxRadius:
        origRow = (radius - minRadius) / (maxRadius - minRadius) * h
        for chn in range(3):
          resultImage[r, c, chn] = interpolated[chn](origCol, origRow)

import matplotlib.pyplot as plt
plt.imshow(resultImage)
plt.show()

Produces:

StackOverflow的扭曲徽标

The performance is terrible, didn't bother to "vectorize". Will update when find out how.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM