2010-03-04 3 views
0

Ecrivez une fonction appelée listenToPicture qui prend une image comme argument. Il montre d'abord l'image. Ensuite, il parcourt tous les 4 pixels sur chaque 4ème ligne et effectue les opérations suivantes. Il calcule le total des niveaux rouge, vert et bleu du pixel, divise cela par 9, puis ajoute le résultat à 24. Ce nombre sera le numéro de note joué par playNote. Cela signifie que plus le pixel est sombre, plus la note est basse; plus le pixel est clair, plus la note est élevée. Il jouera cette note à plein volume (127) pendant un dixième de seconde (100 millisecondes). Chaque fois qu'il passe à une nouvelle ligne, il imprime le numéro de ligne (valeur y) sur la console. Votre fonction principale demandera à l'utilisateur de sélectionner un fichier avec une image. Il imprimera le nombre de notes à lire (qui est le nombre de pixels dans l'image divisé par 16, pourquoi?). Il appellera alors la fonction listenToPicture.Comment faire une boucle sur tous les 4 pixels dans toutes les 4 lignes, en utilisant Python?

Voici ce que j'ai jusqu'à présent, et je ne suis pas sûr comment mettre en place en boucle tous les 4 pixels dans chaque 4ème rangée. Toute aide sera grandement appréciée.

def main(): 
    pic= makePicture(pickAFile()) 
    printNow (getPixels(pic)/16) 
    listenToPicture(pic) 

def listenToPicture(pic): 
    show(pic) 
    w=getWidth(pic) 
    h=getHeight(pic) 

    for px in getPixels(pic):   
     r= getRed(px) 
     g= getGreen(px) 
     b= getBlue(px) 
     tot= (r+g+b)/9 
     playNote= tot + 24 
+0

Le nombre de notes à jouer n'est pas nécessairement # pixels/16. Uniquement si la largeur et la hauteur sont des multiples de 4 –

+1

Utilisez-vous Python Imaging Library (PIL)? –

+0

quelle lib vous utilisez pour charger l'image? comment sont disposées les données de pixels, obtenez-vous un str ou un tableau, est-ce rgbrgbrgb ... ou rrrr ..., ggg ..., bbb ...? –

Répondre

3

gammes étagés viennent à l'esprit range(0, len(), 4) mais je ne sais pas le type de votre pic.

0

Je suppose que le meilleur moyen est de calculer le décalage de 4 lignes, et, quand à la fin de la ligne, l'ajouter à la position actuelle. Vous avez donc deux itérations: une dans la rangée, qui saute 3 pixels, et une à la fin de chaque ligne qui saute 3 lignes. Mais, comme l'a noté msw, sans aucune information sur votre objet pic, nous ne pouvons pas vous aider davantage.

+0

La photo que j'utilise pour tester mon programme est 120x145 pixels, mais le programme est censé fonctionner pour n'importe quelle image que je sélectionne dans le fichier. –

1

Voici quelques blocs de construction, vous pouvez baser votre programme sur:

#!/usr/bin/env python 
import easygui 
import Image 
import numpy 

filename = easygui.fileopenbox() # pick a file 
im = Image.open(filename) # make picture 
image_width, image_height = im.size 
im.show() # show picture 
ar = numpy.asarray(im) # get all pixels 
N = 4 
pixels = ar[::N,::4] # every 4th pixel in every N-th row 
notes = pixels.sum(axis=2)/9 + 24 # compute notes [0, 52] 
print "number of notes to play:", notes.size 

notes peuvent correspondre à des tons différents. J'utilise ici equal tempered scale:

# play the notes 
import audiere 
import time 

d = audiere.open_device() 
# Notes in equal tempered scale 
f0, a = 440, 2**(1/12.) 
tones = [d.create_tone(f0*a**n) for n in range(-26, 27)] # 53 

for y, row in enumerate(notes): 
    print N*y # print original row number 
    for t in (tones[note] for note in row): 
     t.volume = 1.0 # maximum volume 
     t.play() 
     time.sleep(0.1) # wait around 100 milliseconds 
     t.stop() 
1

Vous pourriez vouloir regarder this question. La personne qui a posé cette question semble travailler sur le même projet que vous.

Questions connexes