皆さん、私はちょっとした援助を探しています。私は初心者のプログラマーであり、私が今抱えている問題の1つは、白黒の_.jpg
_イメージをオーディオ信号に変調できるリストに変換しようとしていることです。これはpython SSTVプログラムを作成するための大規模プロジェクトの一部です。
PILモジュールをインポートし、組み込み関数list(im.getdata())
を呼び出そうとしています。私がそれを呼び出すと、pythonがクラッシュします。画像を常に320x240に分割して計算を容易にする方法はありますか?または、間違った関数を呼び出していますか?.
誰か提案があれば、発射してください。誰かがpythonを使用して変調されたオーディオトーンを生成した経験がある場合、喜んで伝えたい「知恵の真珠」を受け入れます。
Getdata()を呼び出してもPythonはクラッシュしません。イメージが破損しているか、PILインストールに何か問題がある可能性があります。別の画像で試すか、使用している画像を投稿してください。
これにより、イメージが希望どおりに分割されます。
from PIL import Image
im = Image.open('um_000000.png')
pixels = list(im.getdata())
width, height = im.size
pixels = [pixels[i * width:(i + 1) * width] for i in xrange(height)]
numpy がインストールされている場合、次を試すことができます。
_data = numpy.asarray(im)
_
(ここで「試して」と言います。なぜgetdata()
が機能しないのかは不明であり、asarray
がgetdataを使用しているかどうかはわかりませんが、テストする価値があります。)
TypeError: 'PixelAccess' object is not iterable
...のようなエラーが発生していると思いますか?
ピクセルにアクセスする方法については、 Image.load のドキュメントをご覧ください。
基本的に、PIL
を使用して画像内のピクセルのリストを取得するには:
from PIL import Image
i = Image.open("myfile.png")
pixels = i.load() # this is not a list, nor is it list()'able
width, height = i.size
all_pixels = []
for x in range(width):
for y in range(height):
cpixel = pixels[x, y]
all_pixels.append(cpixel)
all_pixels
にすべてのピクセルを追加します-ファイルがRGB画像の場合(白黒画像のみを含む場合でも)、これらはTupleになります。例:
(255, 255, 255)
画像をモノクロに変換するには、3つの値を平均するだけです。したがって、最後の3行のコードは次のようになります。
cpixel = pixels[x, y]
bw_value = int(round(sum(cpixel) / float(len(cpixel))))
# the above could probably be bw_value = sum(cpixel)/len(cpixel)
all_pixels.append(bw_value)
または、輝度を取得するには(加重平均):
cpixel = pixels[x, y]
luma = (0.3 * cpixel[0]) + (0.59 * cpixel[1]) + (0.11 * cpixel[2])
all_pixels.append(luma)
または、黒と白の純粋な1ビット:
cpixel = pixels[x, y]
if round(sum(cpixel)) / float(len(cpixel)) > 127:
all_pixels.append(255)
else:
all_pixels.append(0)
おそらくRGB -> BW
変換をより速く行うPIL内のメソッドがありますが、これは機能し、特に遅くはありません。
各行でのみ計算を実行したい場合は、すべてのピクセルを中間リストに追加することをスキップできます。たとえば、各行の平均値を計算するには:
from PIL import Image
i = Image.open("myfile.png")
pixels = i.load() # this is not a list
width, height = i.size
row_averages = []
for y in range(height):
cur_row_ttl = 0
for x in range(width):
cur_pixel = pixels[x, y]
cur_pixel_mono = sum(cur_pixel) / len(cur_pixel)
cur_row_ttl += cur_pixel_mono
cur_row_avg = cur_row_ttl / width
row_averages.append(cur_row_avg)
print "Brighest row:",
print max(row_averages)
PILではなく、 scipy.misc.imread
はまだ興味深いかもしれません:
import scipy.misc
im = scipy.misc.imread('um_000000.png', flatten=False, mode='RGB')
print(im.shape)
与える
(480, 640, 3)
そのため(高さ、幅、チャネル)です。だからあなたはそれを繰り返すことができます
for y in range(im.shape[0]):
for x in range(im.shape[1]):
color = Tuple(im[y][x])
r, g, b = color
または、白または黒のピクセルをカウントする場合
これも解決策です。
from PIL import Image
import operator
img = Image.open("your_file.png").convert('1')
black, white = img.getcolors()
print black[0]
print white[0]
data = numpy.asarray(im)
注意:PILでは、imgはRGBAです。 cv2では、imgはBGRAです。
私の堅牢なソリューション:
def cv_from_pil_img(pil_img):
assert pil_img.mode=="RGBA"
return cv2.cvtColor(np.array(pil_img), cv2.COLOR_RGBA2BGRA)
PILlowがtostring()
をtobytes()
に変更したようです。 RGBAピクセルを抽出してOpenGLテクスチャに入れようとすると、次のことがうまくいきました(glTexImage2D
簡潔にするために省略しています)。
from PIL import Image
img = Image.open("mandrill.png").rotate(180).transpose(Image.FLIP_LEFT_RIGHT)
# use img.convert("RGBA").tobytes() as texels
上記でコメントしたように、問題はPIL内部リスト形式から標準のpythonリストタイプへの変換です。Image.tostring()の方がはるかに高速であり、私の場合、画像データのCRC32ダイジェストを計算する必要がありましたが、それはうまくいきました。
より複雑な計算を実行する必要がある場合、numpyを含むtom10応答が必要な場合があります。
pixVals = list(pilImg.getdata())
出力は、画像からのすべてのRGB値のリストです。
[(248, 246, 247), (246, 248, 247), (244, 248, 247), (244, 248, 247), (246, 248, 247), (248, 246, 247), (250, 246, 247), (251, 245, 247), (253, 244, 247), (254, 243, 247)]