How to find all image coordinates of rendered object? I got my object and I need to know all pixels that are displaying this object in my rendered picture.

I read about a smiliar question here.

update
I tried this code from here:

def tocam(scene, ob):
    cam_vec = cam.matrix_world.to_3x3() * Vector((0, 0, -1))
    R = cam_vec.to_track_quat('-Z', 'Y').to_matrix().to_4x4()

    # scale based on resolution
    S = Matrix() # resX=resY
    # translate such that origin is middle point of image (and hence cam)
    T = Matrix.Translation((-0.5, -0.5, 0))

    ob.data.transform(ob.matrix_world)
    ob.matrix_world = Matrix()
    for v in ob.data.vertices:
        vec = w2cv(scene, cam, v.co)
        v.co = vec.x, vec.y, 0

    ob.data.transform(S * T)

    ob.matrix_world = R
    angle_x = cam.data.angle_x
    x = (0.5 /  tan(angle_x / 2)) * cam_vec.normalized()
    ob.matrix_world.translation = cam.matrix_world.translation + x
    if cam.data.type == 'ORTHO':
        ob.scale *= cam.data.ortho_scale

    res_x = 640
    res_y = 640

    # 2d data printout:
    rnd = lambda i: round(i)

    for v in ob.data.vertices:
        print("{},{}".format(rnd(res_x*v.co.x), rnd(res_y*v.co.y)))


when I plot the points I get this:



but my rendered image is this:



So you can see, that it is not on the correct position and also the shape is not really correct.

Can anyone help me on this? Thanks a lot!
Basically one can just render the masks of the objects as images, import them and generate the arrays. This process is the similar for materials (a mask for every material) and depth.



The script can be (at least) run in 2.8x and 2.79b, just adjust the code with the commented code. If you use 2.79b, put blender in the same folder as the your python.exe.

Master script:

import matplotlib.pyplot as plt
import numpy as np
import glob, os
import PIL.Image as pil
import subprocess

pathToSlave = r'C:\Users\YourName\PycharmProjects\bse\slave.py'

pathToFile = r'C:\Users\YourName\Desktop\segmentation.blend'
fileName = 'segmentation.blend'

pathToRenderOutput = r'C:\Users\YourName\Desktop\trash\\'
pathToBlender = r'C:\Users\YourName\AppData\Local\Programs\Python\Python36\blender-2.79b-windows64\\'

subprocess.call('{}blender {} -b  --python {}'.format(pathToBlender, pathToFile, pathToSlave))

images = glob.glob(os.path.join(pathToRenderOutput, '*.png'))
for img in images:
    arr = np.asarray(pil.open(img))
    arr = arr.sum(axis=-1)
    arr = arr.squeeze()

    plt.imshow(arr)
    plt.show()


Blender part: A mask is generated for every mesh-object

import bpy

bpy.context.scene.render.engine = 'CYCLES'
bpy.context.scene.use_nodes = True
bpy.context.scene.cycles.samples = 1

# For 2.8x
# bpy.context.scene.view_layers["View Layer"].use_pass_object_index = True

# For 2.79b
bpy.context.scene.render.layers["RenderLayer"].use_pass_object_index = True

tree = bpy.data.scenes['Scene'].node_tree
nodes = tree.nodes
links = tree.links
indexOBOutput = tree.get('IndexOB Output')

idMaskList = []
indexPass = 1  # 0 is the default pass

outputPath = r'C:\Users\YourName\Desktop\trash\\'

fileOutput = nodes.new(type="CompositorNodeOutputFile")
fileOutput.base_path = outputPath
fileOutput.file_slots.remove(fileOutput.inputs[0])

for obj in bpy.data.objects:
    if obj.type == 'MESH':
        obj.pass_index = indexPass

        idNode = nodes.new(type='CompositorNodeIDMask')
        idNode.index = indexPass

        links.new(nodes.get('Render Layers').outputs.get('IndexOB'), idNode.inputs[0])
        fileOutput.file_slots.new('Object_{}'.format(indexPass))

        links.new(idNode.outputs[0], fileOutput.inputs[indexPass - 1])

        indexPass += 1

bpy.ops.render.render(use_viewport=False)