3

I know there're many questions similar to mine, but they are a bit too old and not working with newest version of blender.

I found this two, but have no idea how to use them:

bge.types.KX_Camera.getScreenPosition

freestyle.utils.bounding_box(stroke)

And I guess it does what I need, but I can't figure out how to use it. I'm bad with python, and scripting.

I have a scene with a terrain and plants on it. I need to get 2d pixel coordinates of every plant. From top corner to bottom corner, to make a rectangle shape box of every leaf (similar to this, I guess, but maybe I'm wrong).

I have a terrain with plants: enter image description here And I want to get coordinates of every leaf object in json format, to make my software automatically detect position of a leaf object on the picture, when I load a picture and json data into it. So it would look similar to this, once finished: enter image description here Any ideas on how to make it work? At least I would like to know how to get 2d pixel coordinates of multiple objects from rendered image with python? Or is it possible to get 2d coordinates(from top corner to bottom corner) of bounding boxes of every object?

Here's what I've figured out so far, using a default cube with default position and scale:

import bpy
from bpy_extras.object_utils import world_to_camera_view

scene = bpy.context.scene

# needed to rescale 2d coordinates
render = scene.render
res_x = render.resolution_x
res_y = render.resolution_y

obj = bpy.data.objects['Cube']
cam = bpy.data.objects['Camera']

# use generator expressions () or list comprehensions []
verts = (vert.co for vert in obj.data.vertices)
coords_2d = [world_to_camera_view(scene, cam, coord) for coord in verts]

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

print('x,y')
for x, y, distance_to_lens in coords_2d:
    print("{},{}".format(rnd(res_x*x), rnd(res_y*y)))

Console output:

x,y
1308,772
1281,345
946,631
947,166
967,890
967,498
611,779
637,354

Now what's left is to find object's bounding box minimum & maximum x,y 2d coordinates and how to get them?

      # bbox vertices 3d xyz location
        obj = bpy.data.objects['Sphere']
        obj.bound_box

        [v[:] for v in obj.bound_box]

    output:

    [(-0.9999998211860657, -1.0000003576278687, -1.0),
     (-0.9999998211860657, -1.0000003576278687, 1.0), 
(-0.9999998211860657, 1.0, 1.0), 
(-0.9999998211860657, 1.0, -1.0), 
(1.000000238418579, -1.0000003576278687, -1.0), 
(1.000000238418579, -1.0000003576278687, 1.0), 
(1.000000238418579, 1.0, 1.0), 
(1.000000238418579, 1.0, -1.0)]

How to convert those 3d coords to 2d world_to_camera_view x,y coords?

cxnt
  • 397
  • 1
  • 5
  • 27
  • 2
    The script still works if you change the to_mesh call according to: https://docs.blender.org/api/current/bpy.types.Object.html?highlight=to_mesh#bpy.types.Object.to_mesh – brockmann Sep 23 '19 at 14:43
  • I've tried it, It doesn't @brockmann
      File "/Text", line 139, in <module>
      File "/Text", line 135, in main
      File "/Text", line 121, in write_bounds_2d
      File "/Text", line 102, in camera_view_bounds_2d
    RuntimeError: Error: Mesh 'Cube' is outside of main database and can not be removed from it
    
    – cxnt Sep 23 '19 at 14:46
  • 1
    according to my question is it possible to get 2d pixel coordinates(from top corner to bottom corner) of bounding boxes of every object? that could work I guess @brockmann – cxnt Sep 23 '19 at 14:50
  • 3
    Sure, just make the script work @cxnt1 – brockmann Sep 23 '19 at 14:52
  • 1
    How to make bounding boxes appear in rendered image?@brockmann – cxnt Sep 23 '19 at 15:00
  • 1
    Also if you could help me fix this script for me, I'd be very grateful, I'm not good with scripting at all @brockmann – cxnt Sep 23 '19 at 15:03
  • How about creating a the box and adding a wireframe modifier? @cxnt1 – brockmann Sep 23 '19 at 15:10
  • 1
    @brockmann how to add a wireframe modifier? I guess, I could just get coordinates of bounding boxes of every object using this freestyle.utils.bounding_box(stroke)(https://docs.blender.org/api/current/freestyle.utils.html?highlight=bounding%20box#freestyle.utils.bounding_box) but not 100% sure what it does. Could it work? – cxnt Sep 23 '19 at 15:13
  • 3
    Hi. If you have additional information please add it to the main body of the question, such as error messages or information addressing comments. – Ray Mairlot Sep 23 '19 at 16:05
  • 4
    That can be done using https://docs.blender.org/api/current/bpy_extras.object_utils.html#bpy_extras.object_utils.world_to_camera_view and https://docs.blender.org/api/current/gpu.html. From that just loop over the wanted objects, calculate their boundings and use the gpu apis to draw the rectangles. https://i.stack.imgur.com/pZqAg.jpg – lemon Sep 24 '19 at 10:19
  • 1
    @lemon THANKS!! that's exactly, what I was looking for. Could you please show me an example of how to use this please?? – cxnt Sep 24 '19 at 10:44
  • 3
    Sure there is an example here about world_to_camera view https://blender.stackexchange.com/questions/77607/how-to-get-the-3d-coordinates-of-the-visible-vertices-in-a-rendered-image-in-ble/77747#77747 and many examples about gpu in the doc here https://docs.blender.org/api/current/gpu.html – lemon Sep 24 '19 at 10:48
  • 1
    @lemon, will take a look, much appreciated – cxnt Sep 24 '19 at 10:50
  • 1
    @lemon how did you achieve this result as shown on your pic? – cxnt Sep 24 '19 at 10:51
  • note: the final image is obtained mixing the generated bounding drawings with gpu and the render result using the compositor.
  • – lemon Sep 24 '19 at 10:51
  • 1
    @lemon could you please post an answer with script or instruction on how to achieve result as on your pic? I'm having a hard time understanding it – cxnt Sep 24 '19 at 10:59
  • 1
    @lemon how to mix gpu and render result in compositor? – cxnt Sep 24 '19 at 13:02
  • @cxnt1, in this case with a alpha over node. – lemon Sep 24 '19 at 13:05
  • 1
    @lemon and what gpu settings did u use? – cxnt Sep 24 '19 at 13:09
  • This is not gpu settings, this is gpu api that allow to draw the rectangles on an image (see here, many examples about it https://docs.blender.org/api/current/gpu.html) so that it can be mixed with the rendering (whatever engine or engine settings you are using) using the alpha over node. – lemon Sep 24 '19 at 13:12
  • 1
    @lemon which example did u use? 2d rectangle example is something different as I can see – cxnt Sep 24 '19 at 13:19
  • I don't know, never used freestyle apis. But you should try something because we can not extend this discussion so much here. Try something and come back with precise questions, please. – lemon Sep 24 '19 at 13:23
  • 1
    @lemon I mean whenever I try and apply some of the gpu's api examples, they doesnt appear in rendered result – cxnt Sep 24 '19 at 13:29
  • You can use offscreen render then draw using 2D built in shader then retrieve the gl image buffer so that you can copy it into a blender image. Alternatively you can use bgl module, but specs have changed recently and am not sure of what to use for now (something to check, though) – lemon Sep 24 '19 at 13:31