views:

276

answers:

4

Write a function called listenToPicture that takes one picture as an argument. It first shows the picture. Next , it will loop through every 4th pixel in every 4th row and do the following. It will compute the total of the red, green and blue levels of the pixel, divide that by 9, then add the result to 24. That number will be the note number played by playNote. That means that the darker the pixel, the lower the note; the lighter the pixel, the higher the note. It will play that note at full volume (127) for a tenth of a second (100 milliseconds). Every time it moves to a new row, it prints out the row number (y value) on the console. Your main function will ask the user to select a file with a picture. It will print the number of notes to be played (which is the number of pixels in the picture divided by 16; why?). It will then call the listenToPicture function.

Here's what I have so far, and I'm not sure how to set up looping through every 4th pixels in every 4th row. Any help will be greatly appreciate.

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
+3  A: 

Stepped ranges come to mind range(0, len(), 4) but I don't know the type of your pic.

msw
A: 

I would guess the best way is to calculate the offset of 4 rows, and, when at the end of the row, add it to the current position. So you ave two iterations: one within the row, that skip 3 pixels, and one at the end of each row that skip 3 lines. But, as msw noted, without any information on your pic object, we can't help more.

PierreBdR
The pic I am using to test my program is 120x145 pixels, but the program is supposed to work for whatever image I select on file.
Ryan Vanderpool
+1  A: 

Here's some building blocks you could base your program on:

#!/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 can correspond to different tones. I use here 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()
J.F. Sebastian
+1  A: 

You might want to look at this question. The person who asked that question seems to working on the same project as you.

Justin Peel