Я использую Python для генерации изображений, используя пунктирные линии для пунктировки. Период штрихов является постоянным, что меняет соотношение штрих / пространство. Это производит что-то вроде этого:

enter image description here

Однако на этом изображении штрих имеет равномерное происхождение, и это создает неприглядные вертикальные желоба. Поэтому я попытался рандомизировать происхождение, чтобы удалить желоба. Это работает, но есть очевидная закономерность:

enter image description here

Интересно, откуда это взялось, я сделал очень простой тестовый пример со сложенными пунктирными прямыми:

  • коэффициент тире: 50%
  • тире период 20px
  • смещение начала координат от -10px до + 10px с использованием random.uniform(-10.,+10.) (*) (после начального random.seed()

enter image description here

И с добавленной случайностью:

enter image description here

Так что есть еще шаблон. Чего я не понимаю, так это того, что для получения видимого желоба необходимо, чтобы 6 или 7 последовательных значений попадали в один и тот же диапазон (скажем, половина общего диапазона), что должно составлять 1/64 вероятности, но, кажется, происходит много чаще всего в 200 сгенерированных строках.

Я что-то неправильно понимаю? Это только наш человеческий мозг, который видит шаблоны там, где их нет? Может ли быть лучший способ генерировать что-то более «визуально случайное» (python 2.7 и желательно без установки чего-либо)?

(*) частичные пиксели действительны в этом контексте

Приложение: код, который я использую (это скрипт Gimp):

#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-

# Python script for Gimp (requires Gimp 2.10)
# Run on a 400x400 image to see something without having to wait too much
# Menu entry is in "Test" submenu of image menubar

import random,traceback
from gimpfu import *

def constant(minShift,maxShift):
    return 0

def triangle(minShift,maxShift):
    return random.triangular(minShift,maxShift)

def uniform(minShift,maxShift):
    return random.uniform(minShift,maxShift)

def gauss(minShift,maxShift):
    return random.gauss((minShift+maxShift)/2,(maxShift-minShift)/2)

variants=[('Constant',constant),('Triangle',triangle),('Uniform',uniform),('Gauss',gauss)]

def generate(image,name,generator):
    random.seed()
    layer=gimp.Layer(image, name, image.width, image.height, RGB_IMAGE,100, LAYER_MODE_NORMAL)
    image.add_layer(layer,0)
    layer.fill(FILL_WHITE)
    path=pdb.gimp_vectors_new(image,name)

    # Generate path, horizontal lines are 2px apart, 
    # Start on left has a random offset, end is on the right edge right edge
    for i in range(1,image.height, 2):
        shift=generator(-10.,10.)
        points=[shift,i]*3+[image.width,i]*3
        pdb.gimp_vectors_stroke_new_from_points(path,0, len(points),points,False)
    pdb.gimp_image_add_vectors(image, path, 0)

    # Stroke the path
    pdb.gimp_context_set_foreground(gimpcolor.RGB(0, 0, 0, 255))
    pdb.gimp_context_set_stroke_method(STROKE_LINE)
    pdb.gimp_context_set_line_cap_style(0)
    pdb.gimp_context_set_line_join_style(0)
    pdb.gimp_context_set_line_miter_limit(0.)
    pdb.gimp_context_set_line_width(2)
    pdb.gimp_context_set_line_dash_pattern(2,[5,5])
    pdb.gimp_drawable_edit_stroke_item(layer,path)

def randomTest(image):
    image.undo_group_start()
    gimp.context_push()

    try:
        for name,generator in variants:
            generate(image,name,generator)
    except Exception as e:
        print e.args[0]
        pdb.gimp_message(e.args[0])
        traceback.print_exc()

    gimp.context_pop()
    image.undo_group_end()
    return;

### Registration
desc="Python random test"

register(
    "randomize-test",desc,'','','','',desc,"*",
    [(PF_IMAGE, "image", "Input image", None),],[],
    randomTest,menu="<Image>/Test",
)

main()
71
xenoid 1 Май 2019 в 12:16

3 ответа

Лучший ответ

Подумайте об этом так: желоб заметен, пока он не перекрыт (или почти так). Это происходит только тогда, когда две последовательные линии почти полностью не в фазе (черные сегменты в первой линии лежат чуть выше белых сегментов в следующей). Такие экстремальные ситуации случаются только в одном из каждых 10 рядов, следовательно, видимые желоба, которые, кажется, расширяются примерно на 10 рядов, прежде чем будут перекрыты.

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

Чтобы улучшить визуальную случайность, найдите способ сделать последовательные строки зависимыми , а не независимыми, таким образом, чтобы поведение, почти сдвинутое по фазе, появлялось чаще.

46
John Coleman 1 Май 2019 в 11:25

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

Джон Колман имеет точку, когда он говорит:

Чтобы получить лучшую визуальную случайность, найдите способ сделать последовательные линии зависимыми, а не независимыми, таким образом, чтобы поведение почти в противофазе появлялось чаще.

Итак, наконец, лучший способ избежать желобов - это избежать случайности и иметь очень фиксированную схему сдвигов, и хорошо работает 4-фазный цикл 0,25%, 75%, 50%:

enter image description here

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

9
xenoid 1 Май 2019 в 20:37

Это немного нелогично, но при добавлении случайных элементов случайность становится меньше. Если я правильно следую, диапазон каждого элемента составляет 10 - 30 пикселей. Таким образом, общий размер 10 элементов составляет от 100px до 300px, но распределение даже в этом диапазоне отсутствует. Экстремальные значения очень маловероятны, и в среднем они будут довольно близки к 200px, так что появится фундаментальный паттерн 20px. Ваше случайное распределение должно избежать этого.

РЕДАКТИРОВАТЬ: я вижу, что я немного неправильно понял, и все тире 20px со случайным смещением. Итак, я думаю, что просмотр любого 1 вертикального набора штрихов будет казаться случайным, но этот же случайный набор повторяется по всей странице, давая образец.

7
sanyash 1 Май 2019 в 10:34