Skip to content

Commit

Permalink
Bug fixes.
Browse files Browse the repository at this point in the history
  • Loading branch information
ggarra13 committed Sep 25, 2024
1 parent 953e813 commit e10eb6e
Show file tree
Hide file tree
Showing 31 changed files with 2,916 additions and 2,124 deletions.
41 changes: 28 additions & 13 deletions src/ComfyUI/custom_nodes/mrv2/draw/mrv2_annotations_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,13 @@ def _scale_points(points, scale_x, scale_y):
return [(x * scale_x, y * scale_y) for x, y in points]

# Function to draw a circle with a specific width
def _draw_circle(draw, center, radius, width, color):
outer_radius = radius
inner_radius = radius - width / 2
def _draw_circle(draw, center, radius, width, fill_color, outline_color):

# Draw the outer circle
draw.ellipse(
(center[0] - outer_radius, center[1] - outer_radius, center[0] + outer_radius, center[1] + outer_radius),
outline=255,
(center[0] - radius, center[1] - radius, center[0] + radius, center[1] + radius),
fill=fill_color,
outline=outline_color,
width=width
)

Expand Down Expand Up @@ -83,6 +82,7 @@ def create_mask(self, annotations):
for shape in annotation['shapes']:
shape_type = shape['type']
pen_size = int(shape.get('pen_size', 1.0) * scale_factor)
points = None
if shape.get('pts', None):
points = [(point['x'], image_height - point['y'])
for point in shape['pts']]
Expand All @@ -95,17 +95,17 @@ def create_mask(self, annotations):
draw.line(points, fill=255, width=int(pen_size))
elif shape_type == 'ErasePath':
# Draw the path (white color, width defined by 'pen_size')
draw.line(points, fill=0, width=int(pen_size * 1.5))
draw.line(points, fill=0, width=int(pen_size * 1.25))
elif shape_type == 'Arrow':
left_side = [points[1], points[2]]
draw.line(left_side, fill=255, width=int(pen_size))
right_side = [points[1], points[4]]
draw.line(right_side, fill=255, width=int(pen_size))
root = [points[0], points[1]]
draw.line(root, fill=255, width=int(pen_size))
elif shape_type == 'Text':
elif shape_type == 'GL2Text' or shape_type == "Text":
continue
elif shape_type == 'Circle':
elif shape_type == 'Circle' or shape_type == 'FilledCircle':
# Center and radius for the circle
center = shape['center'] # Center of the image
center[1] = image_height - center[1]
Expand All @@ -114,9 +114,25 @@ def create_mask(self, annotations):
center = _scale_points([center], scale_factor, scale_factor)[0]

# Draw the circle with the specified stroke width
_draw_circle(draw, center, radius, pen_size, 255)


fill_color = None
outline_color = 255
if shape_type == 'FilledCircle':
fill_color = 255
outline_color = None
_draw_circle(draw, center, radius, pen_size, fill_color, outline_color)
elif shape_type == 'Rectangle' or shape_type == 'FilledRectangle':
box = [(points[0][0], points[0][1]), (points[2][0], points[2][1])]
if shape_type == 'Rectangle':
draw.rectangle(box, fill=None, outline=255)
else:
draw.rectangle(box, fill=255, outline=None)
elif shape_type == 'Polygon':
draw.polygon(points, fill=None, outline=255)
elif shape_type == 'FilledPolygon':
draw.polygon(points, fill=255, outline=None)
else:
logging.error(f"Unknown shape type {shape_type}")

# Downscale to the target resolution
mask = image.resize((image_width, image_height),
Image.Resampling.LANCZOS)
Expand All @@ -140,6 +156,5 @@ def create_mask(self, annotations):
output_image = output_images[0]
output_mask = output_masks[0]

print("Annotation Image", output_image.shape)
print("Annotation Mask", output_mask.shape)

return (output_image, output_mask)
11 changes: 7 additions & 4 deletions src/docs/HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ v1.2.9
======

- Handle **AV_DISPOSITION_ATTACHED_PIC** properly, instead of skipping it.
- Added PNG decoder so attached png pictures in .wav files are decoded
properly.
- Added a File->Save Annotations as JSON. This allows you to export the
annotations as a .json file.
- Added PNG decoder so attached png pictures in .wav files are decoded properly.
- Added a File->Save Annotations Only. This allows you to export the annotations as a movie or file sequence.
- Added a File->Save Annotations as JSON. This allows you to export the annotations as a .json file.
- Fixed a crashing bug when drawing freehand.
- Fixed disappearing cursor when selecting a drawing tool.
- Added polygon drawing to the drawing tools.
- Polygon, Circle and Rectangle have two modes (outline or filled now). You select the mode by clicking on each triangle edge of the button.

v1.2.8
======
Expand Down
4 changes: 4 additions & 0 deletions src/lib/mrvCore/mrvActionMode.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,15 @@ namespace mrv
kSelection,
kDraw,
kErase,
kPolygon,
kCircle,
kRectangle,
kArrow,
kText,
kRotate,
kFilledCircle,
kFilledRectangle,
kFilledPolygon,
kEditOverwrite,
kEditInsert,
kEditTrim,
Expand Down
2 changes: 2 additions & 0 deletions src/lib/mrvCore/mrvHotkey.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ namespace mrv
Hotkey kSaveImage(false, false, false, false, 0);
Hotkey kSaveImageToFolder(false, false, false, false, 0);
Hotkey kSaveSequence(true, false, false, true, 's');
Hotkey kSaveAnnotationsOnly(false, false, false, false, 0);
Hotkey kSaveAnnotationsAsJson(false, false, false, false, 0);
Hotkey kSaveOTIOEDL(false, false, false, false, 0);
Hotkey kSavePDF(false, false, false, false, 0);
Expand Down Expand Up @@ -369,6 +370,7 @@ namespace mrv

HotkeyEntry(_("Save Movie or Sequence"), &kSaveSequence),
HotkeyEntry(_("Save OTIO Timeline"), &kSaveOTIOEDL),
HotkeyEntry(_("Save Annotations Only"), &kSaveAnnotationsOnly),
HotkeyEntry(_("Save Annotations as JSON"), &kSaveAnnotationsAsJson),
HotkeyEntry(_("Save PDF Document"), &kSavePDF),
HotkeyEntry(_("Save Session"), &kSaveSession),
Expand Down
1 change: 1 addition & 0 deletions src/lib/mrvCore/mrvHotkey.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ namespace mrv
extern Hotkey kSaveImageToFolder;
extern Hotkey kSaveOTIOEDL;
extern Hotkey kSaveSequence;
extern Hotkey kSaveAnnotationsOnly;
extern Hotkey kSaveAnnotationsAsJson;
extern Hotkey kSavePDF;
extern Hotkey kSaveSession;
Expand Down
68 changes: 67 additions & 1 deletion src/lib/mrvCore/mrvMath.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,76 @@

#pragma once

#include <tlCore/Vector.h>

namespace mrv
{
using tl::math::Vector2f;

//! Helper function to calculate the signed area of a triangle
inline int sign(int x1, int y1, int x2, int y2,
int x3, int y3)
{
return (x1 - x3) * (y2 - y3) - (x2 - x3) * (y1 - y3);
}

inline float crossProduct(const Vector2f& p1,
const Vector2f& p2,
const Vector2f& p3)
{
return (p2[0] - p1[0]) * (p3[1] - p1[1]) -
(p2[1] - p1[1]) * (p3[0] - p1[0]);
}

//! Check if a point is inside a triangle
inline bool isPointInTriangle(const Vector2f& pt, const Vector2f& v1,
const Vector2f& v2, const Vector2f& v3)
{
float d1 = crossProduct(pt, v1, v2);
float d2 = crossProduct(pt, v2, v3);
float d3 = crossProduct(pt, v3, v1);

bool hasNeg = (d1 < 0) || (d2 < 0) || (d3 < 0);
bool hasPos = (d1 > 0) || (d2 > 0) || (d3 > 0);

return !(hasNeg && hasPos);
}

//! Function to check if the point (px, py) is inside a triangle formed by
//! (x1, y1), (x2, y2), (x3, y3)
inline bool isPointInTriangle(int px, int py, int x1, int y1, int x2,
int y2, int x3, int y3)
{
int d1 = sign(px, py, x1, y1, x2, y2);
int d2 = sign(px, py, x2, y2, x3, y3);
int d3 = sign(px, py, x3, y3, x1, y1);

bool hasNeg = (d1 < 0) || (d2 < 0) || (d3 < 0);
bool hasPos = (d1 > 0) || (d2 > 0) || (d3 > 0);

// True if all signs are either positive or negative
// (point inside triangle)
return !(hasNeg && hasPos);
}

// Function to determine which triangle the point (px, py) is in
inline
int checkWhichTriangle(int px, int py, int x1, int y1, int x2, int y2)
{
// Check top-left triangle (vertices: (x1, y1), (x2, y1), (x1, y2))
if (isPointInTriangle(px, py, x1, y1, x2, y1, x1, y2)) {
return 0;
}

// Check bottom-right triangle (vertices: (x2, y1), (x2, y2), (x1, y2))
if (isPointInTriangle(px, py, x2, y1, x2, y2, x1, y2)) {
return 1;
}

return -1;
}

//! Fuzzy equal comparison between floats or doubles.
//! Fuzzy equal comparison between ints or doubles.
template < typename T >
inline bool is_equal(const T x1, const T x2, const T e = 1e-5)
{
Expand Down
Loading

0 comments on commit e10eb6e

Please sign in to comment.