Как обработать изображение с помощью Python

У меня есть фотография. Это каллиграфическое письмо.

Мне нужно сделать его заполненным точками так, чтобы все точки следовали друг за другом и соответствовали толщине линии буквы, то есть если линия буквы становится толще, то и точка становится больше. вот пример:

(Оказывается, это именно та буква)

Пробовал работать со скелетом фотографии с помощью OpenCV и Pillow, но ничего не получилось, буду очень рад если поможете, заранее спасибо!

Преобразование расстояния может быть хорошей отправной точкой — вам действительно следует отредактировать заголовок вашего вопроса, чтобы добавить некоторый смысл

Christoph Rackwitz 19.02.2024 22:00

Твой заголовок абсолютно отстой. Пожалуйста, измените его, чтобы оно отражало то, что вы на самом деле спрашиваете.

rayryeng 20.02.2024 03:12

Название здесь не имеет никакого значения: здесь нет вопроса программирования, есть только набор требований. Не по теме, как написано.

David Makogon 20.02.2024 21:25
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
3
60
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Немного поигравшись, пришел к этому довольно наивному подходу, который предполагает итеративное размещение точек и, кажется, дает результаты, несколько соответствующие тому, что, как я полагаю, вы ищете:

import matplotlib.pyplot as plt
from PIL import Image
import numpy as np

# read image into numpy array
img = np.asarray(Image.open('../zZfpE.jpg'))
# binarize and coarse-graining
img = (img[::2, ::2, 0] < 128).astype(int)

def make_dots(
    img, # 2d np array of 1s and 0s
    spd=25, # speed up factor
    marg=0.5, # minimum spacing between dots relative to dot size,
    max_ds=27, # maximum dot diameter in pixels
    min_ds=6, # minimum dot diameter in pixels    
):

    # start with blank image
    img2 = np.zeros(img.shape)
    h, w = img.shape

    # keep track of areas occupied by dots
    occ = set()
    
    ofs = int(spd ** 0.5)

    # iterate over dot sizes, decreasing
    for t in np.arange(max_ds, min_ds, -5):
        # iterate over pixels
        for i in range(0, h, ofs):
            for j in range(0, w, ofs):
                d = 0
                # increase dot diameter while 1. within bounds, b. corners of bounding box are black and 3. not already occupied
                while (
                    i + d < h and j + d < w
                ) and all(
                    [img[i + d, j + d], img[i, j + d], img[i + d, j]]
                ) and not any(
                    [(i + d1, j + d2) in occ for d1, d2 in [(0, d), (d, 0), (d, d)]]
                ):
                    d += 1
                # consider dot only if exceeding threshold
                if d > t:
                    m = int(marg * d)
                    ci = i + d // 2
                    cj = j + d // 2
                    d2 = (d//2) ** 2
                    # iterate over pixels in bounding box of dot + margin
                    for a in range(i-m, i+d+m):
                        for b in range(j-m, j+d+m):
                            # mark pixel as occupied by dot
                            occ.add((a, b))
                            # if within radius, draw to image
                            if (ci - a) ** 2 + (cj - b) ** 2 < d2:
                                img2[a, b] = 1
    return img2


plt.imshow(np.hstack((img, make_dots(img))), cmap='gray_r')
plt.axis('off')
plt.tight_layout()

Хотя он несколько хрупкий/хакерский, он (с адаптацией параметров к имеющимся данным или его модифицированная версия) все же может быть полезен, а если нет, то, по крайней мере, надеюсь, послужит некоторым вдохновением, поэтому поделитесь им здесь.

Спасибо большое, поигрался с параметрами, получилось практически идеально, очень Вам благодарен!

CepBep 20.02.2024 19:56

Пожалуйста, не отвечайте на вопросы не по теме. ФП буквально не предоставил ничего, кроме набора требований. Ваш вопрос на самом деле не отвечает ни на один конкретный вопрос программирования.

David Makogon 20.02.2024 21:25

Другие вопросы по теме