Python의 임의의 임의성
점선을 사용하여 이미지를 생성하기 위해 Python을 사용하고 있습니다. 대시의 기간은 일정하며 대시 / 스페이스 비율이 변경됩니다. 이것은 다음과 같이 생성됩니다.
그러나 그 이미지에서 대시는 원점이 균일하고보기 흉한 수직 홈통을 만듭니다. 그래서 나는 원점을 무작위로 추출하여 거터를 제거하려고했습니다. 이런 종류의 작업이지만 분명한 패턴이 있습니다.
이것이 어디에서 왔는지 궁금해하면서 점선이 쌓인 매우 간단한 테스트 케이스를 만들었습니다.
- 대시 비율 : 50 %
- 대시 마침표 20px
random.uniform(-10.,+10.)
(*)를 사용하여 -10px에서 + 10px로 원점 이동 (이니셜random.seed()
추가 된 임의성 :
그래서 여전히 패턴이 있습니다. 내가 이해하지 못하는 것은 가시적 인 거터를 얻으려면 동일한 범위 (예 : 전체 범위의 절반)에 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()
다음과 같이 생각하십시오. 거 터는 막힐 때까지 (또는 거의 그렇게) 감지 할 수 있습니다. 이것은 두 개의 연속적인 라인이 거의 완전히 위상이 맞지 않을 때만 발생합니다 (첫 번째 라인의 검은 색 세그먼트가 다음 라인의 흰색 세그먼트 거의 위에 놓임). 이러한 극단적 인 상황은 10 행 중 1 행만 발생하므로 방해되기 전에 약 10 행으로 확장되는 것처럼 보이는 홈통이 보입니다.
다른 방식으로 보면 이미지를 인쇄하면 펜으로 쉽게 선을 그릴 수있는 길쭉한 흰색 채널이 있습니다. 왜 당신의 마음은 그들을 인식하지 않아야합니까?
더 나은 시각적 임의성을 얻으려면 거의 위상이 다른 동작이 더 자주 나타나는 방식으로 연속적인 선을 독립적이 아닌 종속적 으로 만드는 방법을 찾으십시오 .
"무작위"그림에서 패턴을 보는 분명한 이유가 하나 이상 있습니다. 400x400 픽셀은 동일한 20x400 픽셀이 20 번 반복됩니다.
따라서 모든 명백한 움직임이 병렬로 20 번 반복되어 뇌가 그림을 분석하는 데 도움이됩니다.
실제로 동일한 10px 너비의 패턴이 흑백을 번갈아 가며 40 번 반복됩니다.
대시 기간을 각 라인에 대해 개별적으로 무작위화할 수 있습니다 (예 : 12 ~ 28).
다음은 해당 코드입니다.
import numpy as np
import random
from matplotlib import pyplot as plt
%matplotlib inline
plt.rcParams['figure.figsize'] = [13, 13]
N = 400
def random_pixels(width, height):
return np.random.rand(height, width) < 0.5
def display(table):
plt.imshow(table, cmap='Greys', interpolation='none')
plt.show()
display(random_pixels(N, N))
def stripes(width, height, stripe_width):
table = np.zeros((height, width))
cycles = width // (stripe_width * 2) + 1
pattern = np.concatenate([np.zeros(stripe_width), np.ones(stripe_width)])
for i in range(height):
table[i] = np.tile(pattern, cycles)[:width]
return table
display(stripes(N, N, 10))
def shifted_stripes(width, height, stripe_width):
table = np.zeros((height, width))
period = stripe_width * 2
cycles = width // period + 1
pattern = np.concatenate([np.zeros(stripe_width), np.ones(stripe_width)])
for i in range(height):
table[i] = np.roll(np.tile(pattern, cycles), random.randrange(0, period))[:width]
return table
display(shifted_stripes(N, N, 10))
def flexible_stripes(width, height, average_width, delta):
table = np.zeros((height, width))
for i in range(height):
stripe_width = random.randint(average_width - delta, average_width + delta)
period = stripe_width * 2
cycles = width // period + 1
pattern = np.concatenate([np.zeros(stripe_width), np.ones(stripe_width)])
table[i] = np.roll(np.tile(pattern, cycles), random.randrange(0, period))[:width]
return table
display(flexible_stripes(N, N, 10, 4))
내 최종 솔루션을 답변으로 게시하지만 다른 사람들에게 찬성 투표하십시오.
John Coleman은 다음과 같이 말합니다.
더 나은 시각적 임의성을 얻으려면 거의 위상이 다른 동작이 더 자주 나타나는 방식으로 연속적인 선을 독립적이 아니라 종속적으로 만드는 방법을 찾으십시오.
So, finally, the best way to avoid gutters is to forego randomness and have a very fixed scheme of shifts, and one that works well is a 4-phase 0,25%,75%,50% cycle:
OK, there is still slight diamond pattern, but it is much less visible than the patterns introduced by the random schemes I tried.
This is slightly counter-intuitive, but as you add random elements together the randomness gets less. If I follow correctly the range of each element is 10px - 30px. So the total size of 10 elements is 100px to 300px, but the distribution is not even across that range. The extremes are very unlikely and on average it will be pretty close to 200px, so that fundamental 20px pattern will emerge. Your random distribution needs to avoid this.
편집 : 나는 약간 오해하고 모든 대시는 무작위 오프셋으로 20px입니다. 따라서 1 개의 수직 대시 세트를 보면 무작위로 보일 것이라고 생각하지만 동일한 무작위 세트가 페이지 전체에서 반복되어 패턴을 제공합니다.
참고 URL : https://stackoverflow.com/questions/55934019/randomness-of-pythons-random
'program story' 카테고리의 다른 글
Node.js 스트림 vs. Observable (0) | 2020.11.02 |
---|---|
Angular2 동적 변경 CSS 속성 (0) | 2020.11.02 |
MSBuild 스크립트 및 VS2010 게시는 Web.config 변환 적용 (0) | 2020.11.02 |
Scala 유형 키워드 : 여러 클래스에서 사용하는 가장 좋은 방법 (0) | 2020.11.02 |
인터페이스 방향을 회전하는 동안 UICollectionView에서 contentOffset 유지 (0) | 2020.11.02 |