The code looks fine to me. Try adding the lines...
assert len(raw) >= 4
assert raw.startswith('\x89PNG')
...directly after the line...
raw = p.stdout.read()
...just to ensure you're getting even vaguely valid data back.
Update
Try this...
from subprocess import check_output
from cStringIO import StringIO
from PIL import Image
raw = check_output(cmd)
buff = StringIO(raw)
im = Image.open(buff)
im.show()
Update #2
Problem is there's a bug in qrcode.exe
whereby, when it's writing to stdout, it tries to convert UNIX line endings to DOS line endings.
Looks like the bug may have gotten fixed in a later version. Try: https://code.google.com/p/qrencode-win32/downloads/detail?name=qrcodegui_setup-3.3.1b.exe&can=1&q=qrencode-win32