13

この画像をPILを使用して3つの部分にカットし、中央の部分を選択する必要があります。どうすればいいのですか?

http://thedilbertstore.com/images/periodic_content/dilbert/dt110507dhct.jpg

4

6 に答える 6

31

このような本当に長い写真があるとしましょう。

写真

そして今、あなたはそれがとても長いので、それをより小さな垂直ビットにスライスしたいと思います。

これを行うPythonスクリプトを次に示します。これは、LaTeXドキュメント用の非常に長い画像を準備する際に役立ちました。

from __future__ import division
import Image
import math
import os

def long_slice(image_path, out_name, outdir, slice_size):
    """slice an image into parts slice_size tall"""
    img = Image.open(image_path)
    width, height = img.size
    upper = 0
    left = 0
    slices = int(math.ceil(height/slice_size))

    count = 1
    for slice in range(slices):
        #if we are at the end, set the lower bound to be the bottom of the image
        if count == slices:
            lower = height
        else:
            lower = int(count * slice_size)  
        #set the bounding box! The important bit     
        bbox = (left, upper, width, lower)
        working_slice = img.crop(bbox)
        upper += slice_size
        #save the slice
        working_slice.save(os.path.join(outdir, "slice_" + out_name + "_" + str(count)+".png"))
        count +=1

if __name__ == '__main__':
    #slice_size is the max height of the slices in pixels
    long_slice("longcat.jpg","longcat", os.getcwd(), 300)

これが出力です

写真


写真


写真

于 2013-01-10T07:04:01.947 に答える
11

Gourneauのソリューションに賛成票を投じたかったのですが、十分な評判がありませんでした。しかし、他の誰かに役立つかもしれない場合に備えて、彼の答えの結果として私が開発したコードを投稿すると思いました。また、ファイル構造を反復処理し、画像の幅を選択する機能も追加しました。

import Image
import os

# Set the root directory
rootdir = 'path/to/your/file/directory'

def long_slice(image_path, out_name, outdir, sliceHeight, sliceWidth):
    img = Image.open(image_path) # Load image
    imageWidth, imageHeight = img.size # Get image dimensions
    left = 0 # Set the left-most edge
    upper = 0 # Set the top-most edge
    while (left < imageWidth):
        while (upper < imageHeight):
            # If the bottom and right of the cropping box overruns the image.
            if (upper + sliceHeight > imageHeight and \
                left + sliceWidth > imageWidth):
                bbox = (left, upper, imageWidth, imageHeight)
            # If the right of the cropping box overruns the image
            elif (left + sliceWidth > imageWidth):
                bbox = (left, upper, imageWidth, upper + sliceHeight)
            # If the bottom of the cropping box overruns the image
            elif (upper + sliceHeight > imageHeight):
                bbox = (left, upper, left + sliceWidth, imageHeight)
            # If the entire cropping box is inside the image,
            # proceed normally.
            else:
                bbox = (left, upper, left + sliceWidth, upper + sliceHeight)
            working_slice = img.crop(bbox) # Crop image based on created bounds
            # Save your new cropped image.
            working_slice.save(os.path.join(outdir, 'slice_' + out_name + \
                '_' + str(upper) + '_' + str(left) + '.jpg'))
            upper += sliceHeight # Increment the horizontal position
        left += sliceWidth # Increment the vertical position
        upper = 0

if __name__ == '__main__':
    # Iterate through all the files in a set of directories.
    for subdir, dirs, files in os.walk(rootdir):
        for file in files:
            long_slice(subdir + '/' + file, 'longcat', subdir, 128, 128)
于 2014-04-09T13:59:02.753 に答える
7

この特定の画像に対して、あなたは

import Image
i = Image.open('dt110507dhct.jpg')
frame2 = i.crop(((275, 0, 528, 250)))
frame2.save('dt110507dhct_frame2.jpg')
于 2011-05-19T13:53:22.073 に答える
4

ボックスが事前にわからない場合は、画像(x方向とy方向の両方)に対して単純なエッジ検索フィルターを実行して、ボックスの境界を検索します。

簡単なアプローチは次のとおりです。

  1. 画像上で水平エッジフィルターを実行します。これで、各ピクセルがそのピクセルの左右の強度の変化を表す画像ができました。つまり、垂直線を「検索」します。
  2. 水平エッジ画像の各列について、その行の平均絶対等級を取得します。結果の1xWIDTHサイズの配列では、最も高い値の位置に垂直線が表示されます。線の幅は1ピクセルを超えるため、ここでは少し賢くする必要があります。
  3. 他の軸についても同じようにして、水平線を見つけます。

ボックスの境界が常に黒であると思われる場合は、最初に黒(または黒に近い)のピクセルのみを抽出することで、前処理を行うことができます。しかし、上記の方法は非常に安定しているはずなので、それが必要になるとは思えません。

于 2011-05-19T14:40:16.137 に答える
3

PILのcrop()メソッドを見てください

http://effbot.org/imagingbook/image.htm

(画像のバウンディングボックスの知識が必要です...画像のサイズが毎日同じであると仮定すると、バウンディングボックスを一度決定して、常に使用できるはずです)。

于 2011-05-19T13:24:03.590 に答える
0
  1. 画像を読み込む
  2. サイズを取得する
  3. クロップ方式を使用する
  4. 真ん中の画像を保存
于 2011-05-19T13:25:18.317 に答える