改变图片中的随机像素,python

2024-06-12 07:22:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我想写一个函数,它将创建一个随机数(m和n之间,包括m和n),在这张图片(http://tinypic.com/r/34il9hu/6)天空中的恒星。我希望星星应该是由单个白色像素随机组成,或者是由4个相邻的白色像素组成的正方形,但我也不想在树枝、月亮或鸟的上方放置一颗1像素的星星

在python中我该怎么做呢?有人能帮忙吗?谢谢!在

到目前为止,我有这个:

我已经开始了,到目前为止,我不知道其中任何一个是正确的,或者即使我在正确的轨道上:

def randomStars(small, large):
   import random
   file = pickAFile()
   pic = makePicture(myPic)
   #x = random.randrange(getWidth(pic))
   #y = random.randrange(getHeight(pic))
   for pixel in pic.getAllPixels():
      if random.random() < 0.25:
         pixel.red = random.randint(256)
         pixel.green = random.randint(256)
         pixel.blue = random.randint(256) 
   show(pic)

我不知道我在做什么:(


Tags: 函数comhttp图片random像素天空randint
3条回答

尝试以下方法:

for n in xrange(number_of_stars):
    # Find a good position
    while True:
        x, y = random_coords_in_image()
        if is_sky(image, x, y):
            break

    # paint a star there
    c = star_colour()

    if large_star():
        image.put(x, y, c)
        image.put(x, y+1, c)
        image.put(x+1, y+1, c)
        image.put(x+1, y, c)
    else:
        image.put(x, y, c)

我使用的函数是非常自解释的;您可以实现is_sky估计给定位置的图像颜色的某些条件。在

Python的标准库没有提供任何功能强大的图像处理代码,但是有一些替代方法可以很容易地安装和使用。我将演示如何使用PIL执行此操作。在

from PIL import Image

def randomStars(small, large):
    import random
    filename = pickAFile()
    pic = Image.open(filename)
    max_x, max_y = pic.size
    pixels = im.load()
    x = random.randrange(max_x)
    y = random.randrange(max_y)
    for i in range(max_x):
        for j in range(max_y):
            if random.random() < 0.25:
                red = random.randint(256)
                green = random.randint(256)
                blue = random.randint(256) 
                pixels[i, j] = (red, green, blue, 1)
    im.show()

show函数不在应用程序中显示图像(为此,您需要某种带有事件循环的GUI,例如tkinter或{});它将文件保存到临时目录中,并运行特定于平台的程序(如Preview或xv)来显示它。在

我想你也会想保存文件。这也很简单:

^{pr2}$

这将使用默认的JPEG设置将其保存回.jpg,依赖于PIL猜测您想要从文件名中得到什么。(这意味着,是的,您可以通过使用'{}-with-stars.png'.format(name)将其保存为PNG。)如果您想要更多的控制,PIL也可以这样做,指定一个显式的格式和特定于格式的选项。在


到目前为止,这只是如何将您现有的代码转换成可以工作的代码,您可以使用它并开始调试;它实际上并不能解决最初的问题。在

I want to write a function that will create a random number (between m and n, inclusive) of stars in the sky of this picture

首先,你需要这个作为循环,而不是所有像素的循环:

for _ in random.randint(m, n):

现在:

I want the stars should be randomly composed of either a single white pixel, or a square of 4 adjacent white pixels.

    x, y = random.randrange(max_x), random.randrange(max_y)
    if random.random() < .5:
        # draw white pixel at [x, y]
        pixels[x, y] = (1, 1, 1, 1)
    else:
        # draw square at [x, y], making sure to handle edges

I also do not want to place a 'star' (of 1 pixel) over the tree branches, the moon or the bird though

你需要定义你如何知道树枝、月亮或鸟的一部分。你能用像素颜色来定义它吗?在

从一个快速的一瞥,似乎你可以。月球的像素比其他任何东西都更亮、更饱和、更偏红等等(除了角落里的美联社标志,它更亮)。鸟和树枝比任何东西都暗。事实上,它们是如此的不同,以至于你甚至不必担心如何进行正确的色彩空间计算;这可能就简单到如下:

r, g, b, a = pixels[x, y]
fake_brightness = r+g+b+a
if fake_brightness < 0.2:
    # Tree or bird, pick a new random position
elif 1.2 < fake_brightness < 2.8:
    # Moon, pick a new random position
else:
    # Sky or API logo, scribble away

(这些数字显然只是凭空捏造出来的,但经过一番尝试和错误,应该可以得到有用的值。)

当然,如果你把这作为一个学习练习,你可能想学习正确的颜色空间数学,甚至可能写一个边缘检测算法,而不是依赖于这个图像是如此简单的解析。在

这看起来是一个很好的例子来尝试superpixels,由skimage实现。你可以用一种更简单的方法来解决你的问题。在

import urllib
import random
import io
import matplotlib.pyplot as plt
import skimage.segmentation
import pandas

# Read the image
f = io.BytesIO(urllib.urlopen('http://oi46.tinypic.com/34il9hu.jpg').read())
img = plt.imread(f, format='jpg')

# Prefer to keep pixels together based on location
# But not too much, so we still get some branches.
superpixel = skimage.segmentation.slic(img, n_segments=200, ratio=20)
plt.imshow(superpixel%7, cmap='Set2')

Superpixels

现在我们有了超级像素,我们可以通过对每个超级像素进行分类来更容易一些。您可以在这里使用一些花哨的分类,但是这个例子非常简单,对于一个蓝色的天空,让我们手工来做。在

^{pr2}$

stars in the sky

相关问题 更多 >