문제 : 다음과 같은 많은 이미지가 포함 된 데이터 세트로 작업하고 있습니다.
이제 색상 팔레트가 이미지의 맨 아래 또는 오른쪽에 있도록 이러한 모든 이미지를 가로 또는 세로 방향으로 배치해야합니다. 이것은 단순히 이미지를 회전하여 수행 할 수 있지만 어떤 이미지를 회전해야하고 어떤 이미지를 회전해서는 안되는지를 파악하는 것이 까다로운 부분입니다.
내가 시도한 것 :
이 작업을 수행하는 가장 좋은 방법은 색상 팔레트와 이미지를 구분하는 흰색 선을 감지하는 것입니다. 하단에 팔레트가있는 모든 이미지를 오른쪽에 배치하기로 결정했습니다.
# yes I am mixing between PIL and opencv (I like the PIL resizing more)
# resize image to be 128 by 128 pixels
img = img.resize((128, 128), PIL.Image.BILINEAR)
img = np.array(img)
# perform edge detection, not sure if these are the best parameters for Canny
edges = cv2.Canny(img, 30, 50, 3, apertureSize=3)
has_line = 0
# take numpy slice of the area where the white line usually is
# (not always exactly in the same spot which probably has to do with the way I resize my image)
for line in edges[75:80]:
# check if most of one of the lines contains white pixels
counts = np.bincount(line)
if np.argmax(counts) == 255:
has_line = True
# rotate if we found such a line
if has_line == True:
s = np.rot90(s)
올바르게 작동하는 예 :
잘못 작동하는 예 :
이것은 이미지의 98 %에서 작동 할 수 있지만 회전하면 안되는 이미지를 회전하거나 회전해야하는 이미지를 회전하지 않는 경우가 있습니다. 이 작업을 수행하는 더 쉬운 방법이 있거나 더 일관된 더 정교한 방법이 있습니까? 수동으로 할 수 있지만 많은 이미지를 다루고 있습니다. 도움 및 / 또는 의견을 보내 주셔서 감사합니다.
테스트 목적으로 내 코드가 실패하는 이미지는 다음과 같습니다.
You can start by thresholding your image by setting a very high threshold like 250 to take advantage of the property that your lines are white. This will make all the background black. Now create a special horizontal kernel with a shape like (1, 15)
and erode your image with it. What this will do is remove the vertical lines from the image and only the horizontal lines will be left.
import cv2
import numpy as np
img = cv2.imread('horizontal2.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, thresh = cv2.threshold(gray, 250, 255, cv2.THRESH_BINARY)
kernel_hor = np.ones((1, 15), dtype=np.uint8)
erode = cv2.erode(thresh, kernel_hor)
질문에서 언급했듯이 색상 구개는 오른쪽 또는 아래쪽에만있을 수 있습니다. 따라서 올바른 영역에 몇 개의 윤곽선이 있는지 테스트 할 수 있습니다. 이를 위해 이미지를 반으로 나누고 올바른 부분을 취하십시오. 윤곽선을 찾기 전에 결과를 확장하여 일반 (3, 3)
커널 로 모든 간격을 채 웁니다 . cv2.RETR_EXTERNAL
윤곽선 찾기를 사용하여 우리가 찾은 수를 계산합니다. 특정 숫자보다 크면 이미지가 올바른면이 위를 향하고 회전 할 필요가 없습니다.
right = erode[:, erode.shape[1]//2:]
kernel = np.ones((3, 3), dtype=np.uint8)
right = cv2.dilate(right, kernel)
cnts, _ = cv2.findContours(right, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
if len(cnts) > 3:
print('No need to rotate')
else:
print('rotate')
#ADD YOUR ROTATE CODE HERE
추신 : 당신이 제공 한 4 개의 이미지를 모두 테스트했으며 잘 작동했습니다. 어떤 이미지에서도 작동하지 않는 경우 알려주십시오.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다