[PYTHON] PIL 색상을 대체하는 가장 좋은 방법은 무엇입니까?
PYTHONPIL 색상을 대체하는 가장 좋은 방법은 무엇입니까?
나는 내 이미지에서 특정 색상을 제거하려고하지만 그것은 내가 바라던대로 잘 작동하지 않습니다. PIL을 사용하여 모든 흰색 픽셀을 투명하게 만들려고 여기에서 보았던 것과 똑같은 것을 시도 했습니까? 그러나 이미지 품질은 약간 손실이 많으므로 제거 된 부분 주변에 홀수 컬러 픽셀의 유령이 남습니다. 세 가지 값이 모두 100 미만이면 픽셀 변경과 같은 작업을 시도했지만 이미지 품질이 좋지 않았기 때문에 주변 픽셀도 검정색이 아니 었습니다.
Python의 PIL을 사용하여 색상과 그 주위를 대체하는 더 좋은 방법을 알고 있습니까? 이것은 아마도 객체를 완전히 제거하는 것을 생각할 수있는 유일한 확실한 화재 방법 일 수 있습니다. 그러나 이것을 수행하는 방법을 생각할 수는 없습니다.
그림은 흰색 바탕에 검정색 텍스트가 있습니다. 그냥 유물을 남기지 않고 이미지에서 텍스트를 완전히 제거하고 싶다고합시다.
누군가의 도움에 정말 감사 할 것입니다! 감사
해결법
-
==============================
1.이미지를 2 차원 배열로 표현해야합니다. 이는 픽셀 목록의 목록을 만들거나 영리한 수학으로 1 차원 배열을 2 차원으로 보는 것을 의미합니다. 그런 다음 타겟팅 된 각 픽셀에 대해 주변 픽셀을 모두 찾아야합니다. 파이썬 생성기로 이렇게 할 수 있습니다 :
이미지를 2 차원 배열로 표현해야합니다. 이는 픽셀 목록의 목록을 만들거나 영리한 수학으로 1 차원 배열을 2 차원으로 보는 것을 의미합니다. 그런 다음 타겟팅 된 각 픽셀에 대해 주변 픽셀을 모두 찾아야합니다. 파이썬 생성기로 이렇게 할 수 있습니다 :
def targets(x,y): yield (x,y) # Center yield (x+1,y) # Left yield (x-1,y) # Right yield (x,y+1) # Above yield (x,y-1) # Below yield (x+1,y+1) # Above and to the right yield (x+1,y-1) # Below and to the right yield (x-1,y+1) # Above and to the left yield (x-1,y-1) # Below and to the left
따라서 다음과 같이 사용하십시오.
for x in range(width): for y in range(height): px = pixels[x][y] if px[0] == 255 and px[1] == 255 and px[2] == 255: for i,j in targets(x,y): newpixels[i][j] = replacementColor
-
==============================
2.가장 좋은 방법은 Gimp에서 사용 된 "alpha to color"알고리즘을 사용하여 색상을 대체하는 것입니다. 그것은 당신의 경우에 완벽하게 작동합니다. 오픈 소스 python photo processor phatch에 PIL을 사용하여이 알고리즘을 다시 구현했습니다. 여기서 전체 구현을 찾을 수 있습니다. 이것은 순수한 PIL 구현이며 다른 의존성을 가지고 있지 않습니다. 기능 코드를 복사하여 사용할 수 있습니다. 다음은 Gimp를 사용하는 샘플입니다.
가장 좋은 방법은 Gimp에서 사용 된 "alpha to color"알고리즘을 사용하여 색상을 대체하는 것입니다. 그것은 당신의 경우에 완벽하게 작동합니다. 오픈 소스 python photo processor phatch에 PIL을 사용하여이 알고리즘을 다시 구현했습니다. 여기서 전체 구현을 찾을 수 있습니다. 이것은 순수한 PIL 구현이며 다른 의존성을 가지고 있지 않습니다. 기능 코드를 복사하여 사용할 수 있습니다. 다음은 Gimp를 사용하는 샘플입니다.
에
검정색을 색상으로 사용하여 이미지에 color_to_alpha 함수를 적용 할 수 있습니다. 그런 다음 교체를 수행 할 이미지를 다른 배경색에 붙여 넣으십시오.
그런데이 구현은 PIL에서 ImageMath 모듈을 사용합니다. getdata를 사용하여 픽셀에 액세스하는 것보다 훨씬 효율적입니다.
편집 : 여기에 전체 코드입니다 :
from PIL import Image, ImageMath def difference1(source, color): """When source is bigger than color""" return (source - color) / (255.0 - color) def difference2(source, color): """When color is bigger than source""" return (color - source) / color def color_to_alpha(image, color=None): image = image.convert('RGBA') width, height = image.size color = map(float, color) img_bands = [band.convert("F") for band in image.split()] # Find the maximum difference rate between source and color. I had to use two # difference functions because ImageMath.eval only evaluates the expression # once. alpha = ImageMath.eval( """float( max( max( max( difference1(red_band, cred_band), difference1(green_band, cgreen_band) ), difference1(blue_band, cblue_band) ), max( max( difference2(red_band, cred_band), difference2(green_band, cgreen_band) ), difference2(blue_band, cblue_band) ) ) )""", difference1=difference1, difference2=difference2, red_band = img_bands[0], green_band = img_bands[1], blue_band = img_bands[2], cred_band = color[0], cgreen_band = color[1], cblue_band = color[2] ) # Calculate the new image colors after the removal of the selected color new_bands = [ ImageMath.eval( "convert((image - color) / alpha + color, 'L')", image = img_bands[i], color = color[i], alpha = alpha ) for i in xrange(3) ] # Add the new alpha band new_bands.append(ImageMath.eval( "convert(alpha_band * alpha, 'L')", alpha = alpha, alpha_band = img_bands[3] )) return Image.merge('RGBA', new_bands) image = color_to_alpha(image, (0, 0, 0, 255)) background = Image.new('RGB', image.size, (255, 255, 255)) background.paste(image.convert('RGB'), mask=image)
-
==============================
3.numpy 및 PIL 사용 :
numpy 및 PIL 사용 :
그러면 이미지가 모양이 매끄러운 배열 (W, H, 3)로로드됩니다. 여기서 W는 너비와 높이가 높이입니다. 배열의 세 번째 축은 3 색을 나타냅니다. 채널, R, G, B.
import Image import numpy as np orig_color = (255,255,255) replacement_color = (0,0,0) img = Image.open(filename).convert('RGB') data = np.array(img) data[(data == orig_color).all(axis = -1)] = replacement_color img2 = Image.fromarray(data, mode='RGB') img2.show()
orig_color는 길이가 3 인 튜플이며 데이터에는 모양 (W, H, 3), NumPy 방송 orig_color를 셰이프 배열 (W, H, 3)에 대입하여 비교 데이터를 수행합니다. == orig_color. 그 결과 모양의 부울 배열 (W, H, 3)이됩니다.
(data == orig_color) .all (축 = -1)은 모양의 부울 배열입니다 (W, H). 데이터의 RGB 색상이 original_color 인 모든 경우 True입니다.
-
==============================
4.
#!/usr/bin/python from PIL import Image import sys img = Image.open(sys.argv[1]) img = img.convert("RGBA") pixdata = img.load() # Clean the background noise, if color != white, then set to black. # change with your color for y in xrange(img.size[1]): for x in xrange(img.size[0]): if pixdata[x, y] == (255, 255, 255, 255): pixdata[x, y] = (0, 0, 0, 255)
-
==============================
5.픽셀을 쉽게 식별 할 수없는 경우 (예 : r <100, g <100 및 b <100)도 검은 색 영역과 정확하게 일치하지 않으면 노이즈가 많음을 의미합니다.
픽셀을 쉽게 식별 할 수없는 경우 (예 : r <100, g <100 및 b <100)도 검은 색 영역과 정확하게 일치하지 않으면 노이즈가 많음을 의미합니다.
가장 좋은 방법은 지역을 식별하고 원하는 색상으로 채우는 것입니다. 수동으로 지역을 식별하거나 가장자리 감지 등으로 할 수 있습니다. http://bitecode.co.uk/2008/07/edge-detection-in-python/
또는 더 정교한 접근법은 객체를 식별하기 위해 opencv (http://opencv.willowgarage.com/wiki/)와 같은 라이브러리를 사용하는 것입니다.
-
==============================
6.이것은 내 코드의 일부이며 결과는 다음과 같습니다. 출처
이것은 내 코드의 일부이며 결과는 다음과 같습니다. 출처
목표
import os import struct from PIL import Image def changePNGColor(sourceFile, fromRgb, toRgb, deltaRank = 10): fromRgb = fromRgb.replace('#', '') toRgb = toRgb.replace('#', '') fromColor = struct.unpack('BBB', bytes.fromhex(fromRgb)) toColor = struct.unpack('BBB', bytes.fromhex(toRgb)) img = Image.open(sourceFile) img = img.convert("RGBA") pixdata = img.load() for x in range(0, img.size[0]): for y in range(0, img.size[1]): rdelta = pixdata[x, y][0] - fromColor[0] gdelta = pixdata[x, y][0] - fromColor[0] bdelta = pixdata[x, y][0] - fromColor[0] if abs(rdelta) <= deltaRank and abs(gdelta) <= deltaRank and abs(bdelta) <= deltaRank: pixdata[x, y] = (toColor[0] + rdelta, toColor[1] + gdelta, toColor[2] + bdelta, pixdata[x, y][3]) img.save(os.path.dirname(sourceFile) + os.sep + "changeColor" + os.path.splitext(sourceFile)[1]) if __name__ == '__main__': changePNGColor("./ok_1.png", "#000000", "#ff0000")
from https://stackoverflow.com/questions/1616767/pil-best-way-to-replace-color by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] numpy에서 가우스 커널 행렬을 효율적으로 계산하는 방법은 무엇입니까? (0) | 2018.10.21 |
---|---|
[PYTHON] 파이썬 버전 전환 (0) | 2018.10.21 |
[PYTHON] 파이썬에서 opencv를 사용하여 이미지의 회전 사각형 영역을 교정하는 방법은 무엇입니까? (0) | 2018.10.21 |
[PYTHON] CSVWriter는 데이터를 쓰는 순간 데이터를 저장하지 않습니다. (0) | 2018.10.21 |
[PYTHON] 훈련 및 테스트 데이터에서 동일한 더미 변수 유지 (0) | 2018.10.21 |