1

目前我正在研究对象识别系统,这需要大量的训练数据。

我正在尝试将 3D 模型转换为一系列灰度图像,旋转模型并以一定的时间间隔对 2D 图像进行采样。

因为我主要在做python,所以我尝试基于pygame和pyopenGL解决这个问题,我找到了这个加载.obj文件的例子,但一开始它不会工作,花了我很长时间找出问题出在哪里。

现在核心问题以某种方式简化为如下:

Point3D 类:

def __init__(self, x = 0, y = 0, z = 0):
    self.x, self.y, self.z = float(x), float(y), float(z)

def rotateX(self, angle):
    """ Rotates the point around the X axis by the given angle in degrees. """
    rad = angle * math.pi / 180
    cosa = math.cos(rad)
    sina = math.sin(rad)
    y = self.y * cosa - self.z * sina
    z = self.y * sina + self.z * cosa
    return Point3D(self.x, y, z)

def rotateY(self, angle):
    """ Rotates the point around the Y axis by the given angle in degrees. """
    rad = angle * math.pi / 180
    cosa = math.cos(rad)
    sina = math.sin(rad)
    z = self.z * cosa - self.x * sina
    x = self.z * sina + self.x * cosa
    return Point3D(x, self.y, z)

def rotateZ(self, angle):
    """ Rotates the point around the Z axis by the given angle in degrees. """
    rad = angle * math.pi / 180
    cosa = math.cos(rad)
    sina = math.sin(rad)
    x = self.x * cosa - self.y * sina
    y = self.x * sina + self.y * cosa
    return Point3D(x, y, self.z)

def project(self, win_width, win_height, fov, viewer_distance):
    """ Transforms this 3D point to 2D using a perspective projection. """
    factor = fov / (viewer_distance + self.z)
    x = self.x * factor + win_width / 2
    y = -self.y * factor + win_height / 2
    return Point3D(x, y, self.z)

类模拟:

    def __init__(self, win_width = 640, win_height = 480):
    pygame.init()

    self.screen = pygame.display.set_mode((win_width, win_height))
    pygame.display.set_caption("Simulation of a rotating 3D Cube (http://codeNtronix.com)")

    self.clock = pygame.time.Clock()

    self.vertices = [
        Point3D(-1,1,-1),
        Point3D(1,1,-1),
        Point3D(1,-1,-1),
        Point3D(-1,-1,-1),
        Point3D(-1,1,1),
        Point3D(1,1,1),
        Point3D(1,-1,1),
        Point3D(-1,-1,1)
    ]

    # Define the vertices that compose each of the 6 faces. These numbers are
    # indices to the vertices list defined above.
    self.faces  = [(0,1,2,3),(1,5,6,2),(5,4,7,6),(4,0,3,7),(0,4,5,1),(3,2,6,7)]

    # Define colors for each face
    self.colors = [(255,0,255),(255,0,0),(0,255,0),(0,0,255),(0,255,255),(255,255,0)]

    self.angle = 0

def run(self):
    """ Main Loop """
    while 1:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

        self.clock.tick(50)
        self.screen.fill((0,32,0))

        # It will hold transformed vertices.
        t = []

        for v in self.vertices:
            # Rotate the point around X axis, then around Y axis, and finally around Z axis.
            r = v.rotateX(self.angle).rotateY(self.angle).rotateZ(self.angle)
            # Transform the point from 3D to 2D
            p = r.project(self.screen.get_width(), self.screen.get_height(), 256, 4)
            # Put the point in the list of transformed vertices
            t.append(p)

        # Calculate the average Z values of each face.
        avg_z = []
        i = 0
        for f in self.faces:
            z = (t[f[0]].z + t[f[1]].z + t[f[2]].z + t[f[3]].z) / 4.0
            avg_z.append([i,z])
            i = i + 1

        # Draw the faces using the Painter's algorithm:
        # Distant faces are drawn before the closer ones.
        for tmp in sorted(avg_z,key=itemgetter(1),reverse=True):
            face_index = tmp[0]
            f = self.faces[face_index]
            pointlist = [(t[f[0]].x, t[f[0]].y), (t[f[1]].x, t[f[1]].y),
                         (t[f[1]].x, t[f[1]].y), (t[f[2]].x, t[f[2]].y),
                         (t[f[2]].x, t[f[2]].y), (t[f[3]].x, t[f[3]].y),
                         (t[f[3]].x, t[f[3]].y), (t[f[0]].x, t[f[0]].y)]
            pygame.draw.polygon(self.screen,self.colors[face_index],pointlist)


        self.angle += 1

        pygame.display.flip()

if name == " main ": Simulation().run()

上面的例子画了一个立方体,一直在旋转,那我怎么能直接得到像素数据呢?什么库或包可以提供我直接获取2D项目的像素数据的能力。(IPL?或 pyopenGL?)

谢谢

4

1 回答 1

0

您可以使用 glreadpixels 进行“截图”。然后,您可以将其传递给 python 图像库,将其作为文件保存到磁盘:https ://stackoverflow.com/a/4122290/2422450

于 2014-12-10T12:12:56.163 回答