mirror of
https://github.com/tiennm99/ArtKrit.git
synced 2026-06-06 10:11:58 +00:00
187 lines
7.4 KiB
Python
187 lines
7.4 KiB
Python
# import os
|
|
# import time
|
|
# from flask import Flask, request, jsonify
|
|
# from flask_cors import CORS
|
|
# from run_models import *
|
|
# from composition_utils import fit_lines, line_leftmost_to_rightmost
|
|
# import cv2
|
|
|
|
# app = Flask(__name__)
|
|
# CORS(app, resources={r"/*": {"origins": "*"}})
|
|
|
|
# # Initialize models at server startup
|
|
# detector, segmentator, processor = init_models()
|
|
|
|
# @app.route("/process_image", methods=['POST'])
|
|
# def process_image():
|
|
# print("Processing image...")
|
|
# json_data = request.get_json()
|
|
# print(json_data)
|
|
# t0 = time.time()
|
|
|
|
# ## read in the image file from the request and save it to a temporary file and get the path
|
|
# image_path = json_data["file_path"]
|
|
|
|
# labels = [l.strip() for l in json_data["text_prompt"].split(",") if l.strip()] # Clean labels
|
|
# threshold_bbox = 0.3
|
|
# polygon_refinement = True
|
|
|
|
# if (not labels) and (len(json_data["custom_rectangles"]) == 0):
|
|
# return jsonify({"error": "No labels or custom rectangles provided"})
|
|
|
|
# if isinstance(image_path, str):
|
|
# image = load_image(image_path)
|
|
|
|
# t_load = time.time()
|
|
# print(f"[Server] Calling Replicate GroundingDINO (labels={labels}, threshold={threshold_bbox})")
|
|
# detections = detect(image, labels, detector, threshold_bbox)
|
|
# t_detect = time.time()
|
|
# print(f"[Server] GroundingDINO call finished in {t_detect - t_load:.2f}s")
|
|
# for custom_rectangle in json_data["custom_rectangles"]:
|
|
# detections.append(DetectionResult.from_dict(
|
|
# {
|
|
# "score": 1.0,
|
|
# "label": "custom_rectangle",
|
|
# "box": {
|
|
# "xmin": int(custom_rectangle[0]),
|
|
# "ymin": int(custom_rectangle[1]),
|
|
# "xmax": int(custom_rectangle[2]),
|
|
# "ymax": int(custom_rectangle[3])
|
|
# }
|
|
# }
|
|
# ))
|
|
|
|
# # Cloud-only: do not request local device; SAM runs on Replicate
|
|
# print("[Server] Calling Replicate SAM model for segmentation")
|
|
# detections = segment(image, detections, segmentator, processor, None, polygon_refinement)
|
|
# t_segment = time.time()
|
|
# print(f"[Server] Replicate SAM call finished in {t_segment - t_detect:.2f}s")
|
|
|
|
# image_array = np.array(image)
|
|
|
|
# visualizaion_parameters = {
|
|
# # "polygon_epsilon": 0.008,
|
|
# "polygon_epsilon": json_data["polygon_epsilon"] * 1e-3,
|
|
# "point_radius": 1e-2,
|
|
# "line_fit_tol": 0.04,
|
|
# "line_radius": 1e-1
|
|
# }
|
|
|
|
# annotated_image, ploygon_contours_list, lines_list, points_to_draw = annotate(image_array,detections, visualizaion_parameters)
|
|
# t_annotate = time.time()
|
|
|
|
# # Plot lines_list on the annotated_image
|
|
# top_lines = min(len(lines_list), 1)
|
|
# for j in range(top_lines):
|
|
# p1, p2 = lines_list[j]
|
|
# cv2.line(annotated_image, tuple(p1), tuple(p2), (0, 255, 0), 20)
|
|
# annotated_image_lines = cv2.cvtColor(annotated_image, cv2.COLOR_BGR2RGB)
|
|
# cv2.imwrite("temp/krita_temp_detection_res.png", img=annotated_image)
|
|
|
|
# # Timing summary
|
|
# try:
|
|
# print(f"[Timing] load={t_load - t0:.2f}s detect={t_detect - t_load:.2f}s segment={t_segment - t_detect:.2f}s annotate={t_annotate - t_segment:.2f}s total={t_annotate - t0:.2f}s")
|
|
# except Exception as e:
|
|
# print(f"[Timing] error computing timings: {e}")
|
|
|
|
# result = {"ploygon_contours": ploygon_contours_list, "composition_lines": lines_list, "points": points_to_draw}
|
|
# return jsonify(result)
|
|
|
|
# @app.route('/regenerate_lines', methods=['POST'])
|
|
# def regenerate_lines():
|
|
# """
|
|
# Regenerate composition lines from manually adjusted points
|
|
# without calling the detection models again
|
|
# """
|
|
# try:
|
|
# json_data = request.get_json()
|
|
# points = json_data.get('points', [])
|
|
# polygon_contours = json_data.get('polygon_contours', [])
|
|
|
|
# if not points:
|
|
# return jsonify({'error': 'Points are required'}), 400
|
|
|
|
# if not polygon_contours:
|
|
# return jsonify({'error': 'Polygon contours are required'}), 400
|
|
|
|
# print(f"[Server] Regenerating lines from {len(points)} manually adjusted points")
|
|
# t0 = time.time()
|
|
|
|
# # Convert points to the format expected by fit_lines
|
|
# # Each point needs to be associated with a polygon index
|
|
# points_with_index = assign_points_to_polygons(points, polygon_contours)
|
|
|
|
# # Create a dummy image array for shape information
|
|
# # We need to infer image dimensions from the polygon contours
|
|
# max_x = max(max(p[0] for p in contour) for contour in polygon_contours)
|
|
# max_y = max(max(p[1] for p in contour) for contour in polygon_contours)
|
|
# image_shape = (int(max_y) + 1, int(max_x) + 1, 3)
|
|
# dummy_image = np.zeros(image_shape, dtype=np.uint8)
|
|
|
|
# # Use the line fitting logic WITHOUT calling annotate or sample_contour_points
|
|
# line_fit_tol = 0.04
|
|
# inlier_threshold = 0.05
|
|
# lines = fit_lines(points_with_index, dummy_image, line_fit_tol=line_fit_tol, inlier_threshold=inlier_threshold)
|
|
|
|
# t_generate = time.time()
|
|
# print(f"[Server] Generated {len(lines)} composition lines in {t_generate - t0:.2f}s")
|
|
|
|
# # Convert lines to the same format as process_image endpoint
|
|
# lines_list = []
|
|
# for line in lines:
|
|
# p1, p2 = line_leftmost_to_rightmost(line)
|
|
# lines_list.append([[int(p1[0]), int(p1[1])], [int(p2[0]), int(p2[1])]])
|
|
|
|
# response = {
|
|
# 'composition_lines': lines_list,
|
|
# 'num_points': len(points),
|
|
# 'num_lines': len(lines_list)
|
|
# }
|
|
|
|
# return jsonify(response)
|
|
|
|
# except Exception as e:
|
|
# print(f"[Server] Error regenerating lines: {str(e)}")
|
|
# import traceback
|
|
# traceback.print_exc()
|
|
# return jsonify({'error': str(e)}), 500
|
|
|
|
# def assign_points_to_polygons(points, polygon_contours):
|
|
# """
|
|
# Assign each point to the polygon it's closest to.
|
|
|
|
# Args:
|
|
# points: List of [x, y] coordinates
|
|
# polygon_contours: List of polygon contours (each is a list of [x, y] coordinates)
|
|
|
|
# Returns:
|
|
# List of tuples: [(point, polygon_index), ...]
|
|
# """
|
|
# points_with_index = []
|
|
|
|
# for point in points:
|
|
# point_array = np.array(point, dtype=np.float32)
|
|
# min_distance = float('inf')
|
|
# closest_polygon_idx = 0
|
|
|
|
# # Find the closest polygon to this point
|
|
# for poly_idx, contour in enumerate(polygon_contours):
|
|
# contour_array = np.array(contour, dtype=np.float32).reshape(-1, 2)
|
|
|
|
# # Calculate distance to each point in the contour
|
|
# distances = np.linalg.norm(contour_array - point_array, axis=1)
|
|
# min_dist_to_contour = np.min(distances)
|
|
|
|
# if min_dist_to_contour < min_distance:
|
|
# min_distance = min_dist_to_contour
|
|
# closest_polygon_idx = poly_idx
|
|
|
|
# points_with_index.append((point, closest_polygon_idx))
|
|
|
|
# print(f"[Server] Assigned {len(points)} points to {len(polygon_contours)} polygons")
|
|
# return points_with_index
|
|
|
|
|
|
# if __name__ == '__main__':
|
|
# print("Starting server")
|
|
# app.run(host='localhost', port=5001, debug=True) |