Python的随机性';这是随机的

Python的随机性';这是随机的,python,random,Python,Random,我正在使用Python生成使用虚线点画的图像。破折号的周期是恒定的,变化的是破折号/间距比。这会产生如下结果: 但是,在该图像中,虚线具有统一的原点,这会创建难看的垂直排水沟。所以我尝试将原点随机化以移除排水沟。这类方法可行,但有一个明显的模式: 想知道这是从哪里来的,我用堆叠的虚线做了一个非常简单的测试用例: 破折号比率:50% 短跑周期20px 使用random.uniform(-10.,+10.)(*)(在初始random.seed()之后)将原点从-10px移动到+10px 增

我正在使用Python生成使用虚线点画的图像。破折号的周期是恒定的,变化的是破折号/间距比。这会产生如下结果:

但是,在该图像中,虚线具有统一的原点,这会创建难看的垂直排水沟。所以我尝试将原点随机化以移除排水沟。这类方法可行,但有一个明显的模式:

想知道这是从哪里来的,我用堆叠的虚线做了一个非常简单的测试用例:

  • 破折号比率:50%
  • 短跑周期20px
  • 使用
    random.uniform(-10.,+10.)
    (*)(在初始
    random.seed()之后)将原点从-10px移动到+10px

增加了随机性:

所以还是有规律的。我不明白的是,要得到一个可见的排水沟,你需要有6到7个连续的值落在相同的范围内(比如说,总范围的一半),这应该是1/64的概率,但似乎在生成的200行中发生得更多

我是不是误解了什么?只是我们的大脑在看没有模式的模式吗?有没有更好的方法来生成更“视觉随机”的模式(python 2.7,最好不安装任何东西)

(*)部分像素在该上下文中有效

附件:我使用的代码(这是一个Gimp脚本):

!/usr/bin/env python
#-*-编码:iso-8859-15-*-
#Gimp的Python脚本(需要Gimp 2.10)
#在400x400图像上运行以查看内容,而无需等待太久
#菜单项位于图像菜单栏的“测试”子菜单中
导入随机、回溯
从gimpfu进口*
def常数(最小换档、最大换档):
返回0
def三角(minShift、maxShift):
返回随机三角形(minShift、maxShift)
def均匀(最小换档、最大换档):
返回随机均匀(minShift、maxShift)
def高斯(最小移位、最大移位):
返回random.gauss((minShift+maxShift)/2,(maxShift-minShift)/2)
变量=[(‘常数’、常数)、(‘三角形’、三角形)、(‘均匀’、均匀)、(‘高斯’、高斯)]
def生成(图像、名称、生成器):
random.seed()
layer=gimp.layer(图像、名称、图像.宽度、图像.高度、RGB_图像、100、层模式\u正常)
图像。添加_层(层,0)
图层填充(填充为白色)
path=pdb.gimp\u vectors\u new(图像,名称)
#生成路径,水平线相隔2倍,
#从左开始有一个随机偏移,从右到右结束
对于范围内的i(1,image.height,2):
班次=发电机(-10,10.)
点数=[shift,i]*3+[image.width,i]*3
pdb.gimp_向量_笔划_新_自_点(路径,0,len(点),点,假)
pdb.gimp_image_add_向量(图像,路径,0)
#轻描淡写
pdb.gimp\u上下文\u集合\u前景(gimpcolor.RGB(0,0,0255))
pdb.gimp_上下文_集合_笔划_方法(笔划线)
pdb.gimp\u上下文\u集合\u线\u帽\u样式(0)
pdb.gimp\u上下文\u集\u线\u连接\u样式(0)
pdb.gimp\u上下文\u设置\u线\u斜接\u限制(0)
pdb.gimp_上下文_集合_线_宽度(2)
pdb.gimp\u上下文\u集合\u线\u破折号\u模式(2,[5,5])
pdb.gimp\u可绘制\u编辑\u笔划\u项目(图层、路径)
def随机测试(图像):
image.undo_group_start()
gimp.context_push()
尝试:
对于名称,生成器的变体为:
生成(图像、名称、生成器)
例外情况除外,如e:
打印e.args[0]
pdb.gimp_消息(e.args[0])
traceback.print_exc()
gimp.context_pop()
image.undo_group_end()
返回;
###登记
desc=“Python随机测试”
登记册(
“随机试验”,描述,,,,,,,,,描述,*,
[(PF_图像,“图像”,“输入图像”,无),],[],
随机测试,菜单=“/Test”,
)
main()

这有点违反直觉,但当你将随机元素添加到一起时,随机性会变小。如果我正确地遵循,每个元素的范围是10px-30px。因此,10个元素的总大小是100px到300px,但分布并不均匀。极端情况是非常不可能的,平均而言,它将非常复杂ose到200px,这样基本的20px模式就会出现。你的随机分布需要避免这种情况


编辑:我发现我有点误解了,所有的破折号都是20px,带有随机偏移量。因此,我认为查看任何一组垂直破折号都会显得随机,但相同的随机集在页面上重复出现,给出了模式。

这样想:排水沟在被阻塞(或几乎如此)之前是可以感知的。只有当两条连续线路几乎完全不同步时才会发生这种情况(第一条线路中的黑色线段几乎位于下一条线路中的白色线段的上方)。这种极端情况仅发生在每10行中的一行,因此可见的排水沟似乎在被阻塞之前延伸了约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))
将numpy导入为np
随机输入
从matplotlib导入pyplot作为plt
%matplotlib内联
plt.rcParams['figure.figsize']=[13,13]
N=400
def随机_像素(宽度、高度):
返回np.rand.rand(高度、宽度)<0.5
def显示(表格):
plt.imshow(表,
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))