반응형

Pillow 모듈을 사용해 큰 이미지에서 작은 부분을 찾을 수 있다. 예를 들어 아래 Target과 같이 작은 부분을 큰 Source에서 찾아야 하는 경우이다.


2018/12/02 - [Software/Python] - Pillow 이미지 서치(Image Search) 2

2019/07/08 - [Software/OpenCV] - Template Matching(Image Searching) - 부분 이미지 검색

2019/07/10 - [Software/OpenCV] - Template Matching(Image Searching) for multiple objects - 반복되는 이미지 모두 찾기

2019/07/12 - [Software/OpenCV] - Template Matching(Image Searching) with a mask for multiple objects - 마스크를 이용해 (배경이 다른) 반복되는 이미지 모두 찾기


Target:


Source:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
from PIL import Image
from PIL import ImageDraw
from PIL import ImageChops
from PIL import ImageStat
import sys
 
source = Image.open("source.bmp")
sx, sy = source.size
target = Image.open("target.bmp")
tx, ty = target.size
 
print("Source size: ", source.size)
print("Target size: ", target.size)
 
trial = 0 # Image search 시도 횟수.
 
def Search(cx, cy):
    #for y in range(ty):
    #    for x in range(tx):
    #        if target.getpixel((x, y)) == source.getpixel((cx + x, cy + y)):
    #            continue
    #        else:
    #            return False
    #return True
 
    compare = source.crop((cx, cy, cx + tx, cy + ty)) # 소스에서 타겟으로 판단되는 위치의 이미지를 타겟 사이즈 만큼 잘라낸다.
    # Returns a rectangular region from this image. The box is a 4-tuple defining the left, upper, right, and lower pixel coordinate.
    print("Compare size: ", compare.size)
 
    diff = ImageChops.difference(compare, target) # 타겟과 타겟으로 판단되는 부분의 픽셀값 비교.
    stat = ImageStat.Stat(diff)
    global trial
    if stat.sum == [000]:
        print("Target found(checksum): ", stat.sum)
        return True
    else:
        trial += 1
        return False
 
draw = ImageDraw.Draw(source)    # Creates an object that can be used to draw in the given image.
 
for y in range(sy - ty):        # 소스의 처음부터 타겟 사이즈를 뺀 위치 까지 검색을 시작 한다.
    for x in range(sx - tx):    # 처음 (2 X 2)개 픽셀의 값이 같다면 Search()로 타겟 사이즈 전체를 다시 확인한다.
        if source.getpixel((x, y)) == target.getpixel((00)) and source.getpixel((x + 1, y)) == target.getpixel((10)) \
            and source.getpixel((x, y + 1)) == target.getpixel((01)) and source.getpixel((x + 1, y + 1)) == target.getpixel((11)):
            if Search(x, y) == True:
                print("Top left point: (%d, %d)" %(x, y))
                print("Center of targe point: (%d, %d)" %(x + target.width / 2, y + target.height / 2))
                print("Number of total wrong detection: ", trial)
                draw.rectangle((x, y, x + target.width, y + target.height), outline = (25500))
                # Draws a rectangle. 소스 이미지의 타겟 부분에 빨간 사각형을 그린다.
                source.show()
                sys.exit()
            else:
                print("At (%d, %d): Target not found" %(x, y))
                print("Wrong detection count: ", trial)
 
print("Image search failed.")
cs




결과: 리트리버의 앞발 쪽에서 Target을 찾았다.

반응형
Posted by J-sean
: