沿极坐标系的图像信息 [英] image information along a polar coordinate system

查看:126
本文介绍了沿极坐标系的图像信息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一组png图像,我想用Python和相关工具处理。每个图像代表一个具有已知尺寸的物理对象。

I have a set of png images that I would like to process with Python and associated tools. Each image represents a physical object with known dimensions.

在每个图像中,对象的特定特征在某个像素/物理位置。每张图片的位置都不同。

In each image there is a specific feature of the object at a certain pixel/physical location. The location is different for each image.

我想在给定图像上施加极坐标系,原点位于此要素的位置。

I would like to impose a polar coordinate system on a given image with the origin at the location of this feature.

我希望能够得到以下信息:
- 图像强度作为给定极角的径向位置的函数
- 当在所有极角上平均值时,图像强度作为径向位置的函数。

I would then like to be able to get the following information: - the image intensity as a function of radial position for a given polar angle - the image intensity as a function of radial position when values are averaged over all polar angles.

我在Python编程和在NumPy中使用许多函数方面经验丰富SciPy,但在图像分析方面,我是一个完整的新手。

I am experienced in Python programming and the use of many functions in NumPy and SciPy, but I am a complete novice when it comes to image analysis.

如果您有任何建议可以解决这个问题,我将不胜感激。

I would appreciate any advice you can give me on possible approaches to use to solve this problem.

谢谢你。

推荐答案

你所描述的并不是传统意义上的图像处理,但它很容易做到numpy等等。

What you're describing isn't exactly image processing in the traditional sense, but it's fairly easy to do with numpy, etc.

这是一个相当大的例子,做了一些你提到的事情,让你指向正确的方向......注意,示例图像都显示结果对于图像中心的原点,但函数采用原点参数,因此您应该能够根据自己的需要直接调整。

Here's a rather large example doing some of the things you mentioned to get you pointed in the right direction... Note that the example images all show results for the origin at the center of the image, but the functions take an origin argument, so you should be able to directly adapt things for your purposes.

import numpy as np
import scipy as sp
import scipy.ndimage

import Image

import matplotlib.pyplot as plt

def main():
    im = Image.open('mri_demo.png')
    im = im.convert('RGB')
    data = np.array(im)

    plot_polar_image(data, origin=None)
    plot_directional_intensity(data, origin=None)

    plt.show()

def plot_directional_intensity(data, origin=None):
    """Makes a cicular histogram showing average intensity binned by direction
    from "origin" for each band in "data" (a 3D numpy array). "origin" defaults
    to the center of the image."""
    def intensity_rose(theta, band, color):
        theta, band = theta.flatten(), band.flatten()
        intensities, theta_bins = bin_by(band, theta)
        mean_intensity = map(np.mean, intensities)
        width = np.diff(theta_bins)[0]
        plt.bar(theta_bins, mean_intensity, width=width, color=color)
        plt.xlabel(color + ' Band')
        plt.yticks([])

    # Make cartesian coordinates for the pixel indicies
    # (The origin defaults to the center of the image)
    x, y = index_coords(data, origin)

    # Convert the pixel indices into polar coords.
    r, theta = cart2polar(x, y)

    # Unpack bands of the image
    red, green, blue = data.T

    # Plot...
    plt.figure()

    plt.subplot(2,2,1, projection='polar')
    intensity_rose(theta, red, 'Red')

    plt.subplot(2,2,2, projection='polar')
    intensity_rose(theta, green, 'Green')

    plt.subplot(2,1,2, projection='polar')
    intensity_rose(theta, blue, 'Blue')

    plt.suptitle('Average intensity as a function of direction')

def plot_polar_image(data, origin=None):
    """Plots an image reprojected into polar coordinages with the origin
    at "origin" (a tuple of (x0, y0), defaults to the center of the image)"""
    polar_grid, r, theta = reproject_image_into_polar(data, origin)
    plt.figure()
    plt.imshow(polar_grid, extent=(theta.min(), theta.max(), r.max(), r.min()))
    plt.axis('auto')
    plt.ylim(plt.ylim()[::-1])
    plt.xlabel('Theta Coordinate (radians)')
    plt.ylabel('R Coordinate (pixels)')
    plt.title('Image in Polar Coordinates')

def index_coords(data, origin=None):
    """Creates x & y coords for the indicies in a numpy array "data".
    "origin" defaults to the center of the image. Specify origin=(0,0)
    to set the origin to the lower left corner of the image."""
    ny, nx = data.shape[:2]
    if origin is None:
        origin_x, origin_y = nx // 2, ny // 2
    else:
        origin_x, origin_y = origin
    x, y = np.meshgrid(np.arange(nx), np.arange(ny))
    x -= origin_x
    y -= origin_y
    return x, y

def cart2polar(x, y):
    r = np.sqrt(x**2 + y**2)
    theta = np.arctan2(y, x)
    return r, theta

def polar2cart(r, theta):
    x = r * np.cos(theta)
    y = r * np.sin(theta)
    return x, y


def bin_by(x, y, nbins=30):
    """Bin x by y, given paired observations of x & y.
    Returns the binned "x" values and the left edges of the bins."""
    bins = np.linspace(y.min(), y.max(), nbins+1)
    # To avoid extra bin for the max value
    bins[-1] += 1 

    indicies = np.digitize(y, bins)

    output = []
    for i in xrange(1, len(bins)):
        output.append(x[indicies==i])

    # Just return the left edges of the bins
    bins = bins[:-1]

    return output, bins

def reproject_image_into_polar(data, origin=None):
    """Reprojects a 3D numpy array ("data") into a polar coordinate system.
    "origin" is a tuple of (x0, y0) and defaults to the center of the image."""
    ny, nx = data.shape[:2]
    if origin is None:
        origin = (nx//2, ny//2)

    # Determine that the min and max r and theta coords will be...
    x, y = index_coords(data, origin=origin)
    r, theta = cart2polar(x, y)

    # Make a regular (in polar space) grid based on the min and max r & theta
    r_i = np.linspace(r.min(), r.max(), nx)
    theta_i = np.linspace(theta.min(), theta.max(), ny)
    theta_grid, r_grid = np.meshgrid(theta_i, r_i)

    # Project the r and theta grid back into pixel coordinates
    xi, yi = polar2cart(r_grid, theta_grid)
    xi += origin[0] # We need to shift the origin back to 
    yi += origin[1] # back to the lower-left corner...
    xi, yi = xi.flatten(), yi.flatten()
    coords = np.vstack((xi, yi)) # (map_coordinates requires a 2xn array)

    # Reproject each band individually and the restack
    # (uses less memory than reprojection the 3-dimensional array in one step)
    bands = []
    for band in data.T:
        zi = sp.ndimage.map_coordinates(band, coords, order=1)
        bands.append(zi.reshape((nx, ny)))
    output = np.dstack(bands)
    return output, r_i, theta_i

if __name__ == '__main__':
    main()

原始图片:

投射到极坐标中:

作为图像中心方向函数的强度:

Intensity as a function of direction from the center of the image:

这篇关于沿极坐标系的图像信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆