Как избавиться от линий на рисунке? И как я могу уменьшить количество линий, необходимых для создания рисунка?Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Как избавиться от линий на рисунке? И как я могу уменьшить количество линий, необходимых для создания рисунка?

Сообщение Anonymous »

Я пытаюсь создать код Python, который принимает изображение и преобразует его в JavaScript, чтобы мой Blot by Hack Club мог прочитать этот JS и создать это изображение. Документация по пятнам. В настоящее время мой код делает это, но рисует случайные линии поверх кода. Кроме того, код генерирует множество строк для обработки пятна. Как мне найти наилучшее качество с наименьшим количеством генерируемых строк
from PIL import Image, ImageOps
import numpy as np
import cv2
from skimage import measure, transform
import math

# Set the detail level (1 for maximum detail, 0 for minimal detail)
detail_level = 0.4

# Function to process the image and extract edges with higher precision
def process_image(image_path):
# Load image and convert to grayscale
image = Image.open(image_path).convert("L")
image = ImageOps.mirror(image) # Mirror the image horizontally
image = ImageOps.invert(image) # Invert to make the background black and foreground white
image = image.rotate(180) # Rotate the image by 180 degrees
image_array = np.array(image)

# Calculate ksize (ensuring it's odd and positive)
ksize_value = max(3, int(round(-3.333333333333 * detail_level + 5.666666666666666667)))
if ksize_value % 2 == 0:
ksize_value += 1
ksize = (ksize_value, ksize_value)

# Apply a slight blur to reduce noise
blurred = cv2.GaussianBlur(image_array, ksize, 0)

# Use Canny edge detection with lower thresholds for more sensitivity
canny_threshold1 = int(round(-33.333333333 * detail_level + 56.6666666666667))
canny_threshold2 = int(round(-83.33333333 * detail_level + 166.666666667))
edges = cv2.Canny(blurred, canny_threshold1, canny_threshold2)

# Optionally, thicken the edges slightly
edges = transform.rescale(edges, 1.0, anti_aliasing=True)
edges = cv2.dilate(edges, np.ones((2,2),np.uint8), iterations=1)

# Use contours to find connected components
contours = measure.find_contours(edges, 0.8)

return contours, image_array.shape

# Function to generate the Blot code
def generate_blot_code(contours, dimensions, detail_level=0.8, min_distance_threshold=5):
print("Generating Blot code...")
lines = []

# Set a fixed tolerance for fine control over details
max_tolerance = 0.5 # More detail
min_tolerance = 0.1 # Minimal simplification
tolerance = (1 - detail_level) * (max_tolerance - min_tolerance) + min_tolerance

# Calculate bounding box of all contours
all_points = np.concatenate(contours)
min_y, min_x = np.min(all_points, axis=0)
max_y, max_x = np.max(all_points, axis=0)

# Calculate scale and translation to center the drawing
scale_x = (dimensions[1] - 1) / (max_x - min_x)
scale_y = (dimensions[0] - 1) / (max_y - min_y)
scale = min(scale_x, scale_y) # Maintain aspect ratio by using the smallest scale factor

translate_x = (dimensions[1] - (max_x - min_x) * scale) / 2 - min_x * scale
translate_y = (dimensions[0] - (max_y - min_y) * scale) / 2 - min_y * scale

# Initialize line counter
line_counter = 0

for contour in contours:
# Smooth the contour and simplify based on the detail level
smoothed_contour = measure.approximate_polygon(contour, tolerance=tolerance)

if len(smoothed_contour) >= 2: # Only consider meaningful contours
prev_x, prev_y = smoothed_contour[0] # Initialize with the first point
for i in range(1, len(smoothed_contour)):
y1, x1 = prev_y, prev_x
y2, x2 = smoothed_contour

# Scale and translate coordinates
x1_scaled = int(x1 * scale + translate_x)
y1_scaled = int(y1 * scale + translate_y)
x2_scaled = int(x2 * scale + translate_x)
y2_scaled = int(y2 * scale + translate_y)

# Calculate the Euclidean distance between consecutive points
distance = math.sqrt((x2_scaled - x1_scaled) ** 2 + (y2_scaled - y1_scaled) ** 2)

# Only draw the line if the distance is greater than the threshold
if distance > min_distance_threshold:
lines.append(f"finalLines.push([[{x1_scaled}, {y1_scaled}], [{x2_scaled}, {y2_scaled}]]);\n")
prev_x, prev_y = x2, y2 # Update the previous point to the current point

# Increment line counter
line_counter += 1
if line_counter % 50 == 0:
lines.append(f"console.log('{line_counter} lines completed');\n")

blot_code = [
"// Produced by Aditya Anand's Blotinator, not human-written\n",
f"setDocDimensions({dimensions[0]}, {dimensions[1]});\n",
"const finalLines = [];\n"
]
blot_code.extend(lines)
blot_code.append("drawLines(finalLines);")

return blot_code

# Main function
if __name__ == "__main__":
# Use the correct image path
image_path = '/Users/vivaanshahani/Downloads/IMG_9654 3.jpg'
# Process the image
contours, dimensions = process_image(image_path)

# Generate the Blot code with the specified detail level
blot_code = generate_blot_code(contours, dimensions, detail_level)

# Write the Blot code to a file
output_path = "/Users/vivaanshahani/Downloads/Blotcode.js"
with open(output_path, "w") as file:
file.writelines(blot_code)

print(f"Blot code generated and saved to {output_path}")



Подробнее здесь: https://stackoverflow.com/questions/790 ... the-amount
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»