Как обрезать несколько прямоугольников или квадратов из JPEG? - PullRequest
2 голосов
/ 05 июня 2019

У меня есть JPEG, откуда я хочу обрезать часть, содержащую график (тот, что в нижней части).

На данный момент я использовал этот код для достижения того же:

from PIL import Image

img = Image.open(r'D:\aakash\graph2.jpg')
area = (20, 320, 1040, 590)
img2 = img.crop(area)
# img.show()
img2.show()

Но я достиг этого, угадав x1, y1, x2, y2 несколько раз, чтобы прийти к этому (угадайте).

Изображение перед кадрированием: enter image description here

Изображение после обрезки: enter image description here

Я совершенно новичок в области обрезки изображений на основе некоторой логики.Как я могу успешно обрезать все графики, чтобы создать отдельные изображения при одинаковых позициях?

Обновление: Я считаю, что это не является возможным дубликатом этой проблемы, потому что, хотя логически это то же самое, но способ работы логики кластеризации будет другим.В этом вопросе есть только две вертикальные белые линии, которые нужно разделить, но здесь есть две горизонтальные и две вертикальные линии, и я едва знаю, как использовать KMeans для решения этого типа кластеризации изображений.

Помощь от кого-то, кто является экспертом с Kleans Kleans для решения этой проблемы, будет высоко оценена.

Ответы [ 3 ]

3 голосов
/ 06 июня 2019

Вот третий способ сделать это без необходимости писать Python.Он просто использует ImageMagick в Терминале - он установлен на большинстве дистрибутивов Linux и доступен для macOS и Windows.

По сути, он использует те же методы, что и другие мои ответы - порог, медианный фильтри «Анализ подключенных компонентов» , он же «маркировка» .

magick article.jpg -colorspace gray -threshold 95% -median 19x19  \
    -define connected-components:verbose=true                     \
    -define connected-components:area-threshold=100               \
    -connected-components 4 -auto-level output.png

Пример вывода

Objects (id: bounding-box centroid area mean-color):
  4: 963x241+38+333 519.0,453.0 231939 srgb(0,0,0)
  0: 1045x590+0+0 528.0,204.0 155279 srgb(255,255,255)
  2: 393x246+292+73 488.0,195.5 96534 srgb(0,0,0)
  3: 303x246+698+73 849.0,195.5 74394 srgb(0,0,0)
  1: 238x246+39+73 157.5,195.5 58404 srgb(0,0,0)

В выводе есть строка заголовка, в которой указано, что это за поля, а затем по одной строке для каждого сгустка, найденного на изображении.Давайте посмотрим на линию:

2: 393x246+292+73 488.0,195.5 96534 srgb(0,0,0)

Это означает, что существует шарик шириной 393 пикселя и высотой 246 пикселя со смещением 292,73 от верхнего левого угла, который мы можем нарисовать полупрозрачным синим цветом.с этим:

magick article.jpg -fill "rgba(0,0,255,0.5)" -draw "rectangle 292,73 685,319" result.png

enter image description here

И мы можем обрезать с этим:

magick article.jpg -crop 393x246+292+73 result.png

enter image description here

Помеченное изображение (output.png) с самой первой команды выглядит следующим образом - вы увидите, что каждый шарик помечен своим цветом (оттенок серого):

enter image description here


Обратите внимание, что если ваша версия ImageMagick v6 или старше, вам нужно использовать convert вместо magick во всех вышеперечисленных командах.

2 голосов
/ 06 июня 2019

Вот еще один способ сделать это, но с использованием PIL / Pillow и skimage вместо OpenCV:

#!/usr/local/bin/python3

import numpy as np
from PIL import Image, ImageFilter
from skimage.measure import label, regionprops

# Load image and make Numpy version and greyscale PIL version
pim = Image.open('article.jpg')
n   = np.array(pim)
pgr = pim.convert('L')

# Threshold to make black and white
thr = pgr.point(lambda p: p < 230 and 255)
# Following line is just for debug
thr.save('result-1.png')

# Median filter to remove noise
fil = thr.filter(ImageFilter.MedianFilter(11))
# Following line is just for debug
fil.save('result-2.png')

# Make Numpy version for skimage to use
nim = np.array(fil)

# Image is now white blobs on black background, so label() it
label_image=label(nim)

# Iterate through blobs, saving each to disk
i=0
for region in regionprops(label_image):
   if region.area >= 100:
      # Extract rectangle containing blob and save
      name="blob-" + str(i) + ".png"
      minr, minc, maxr, maxc = region.bbox
      Image.fromarray(n[minr:maxr,minc:maxc,:]).save(name)
      i = i + 1

, что дает следующие выходные изображения:

enter image description here

enter image description here

enter image description here

enter image description here

И промежуточные отладочные изображения: result-1.png:

enter image description here

и result-2.png:

enter image description here

2 голосов
/ 06 июня 2019

Вот способ сделать это, используя метод OpenCV findContours().

#!/usr/bin/env python3

import numpy as np
import cv2

# Load image
im = cv2.imread('article.jpg',cv2.IMREAD_UNCHANGED)

# Create greyscale version
gr = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)

# Threshold to get black and white
_,grthresh = cv2.threshold(gr,230,255,cv2.THRESH_BINARY)
cv2.imwrite('result-1.png',grthresh)

# Median filter to remove JPEG noise
grthresh = cv2.medianBlur(grthresh,11)
cv2.imwrite('result-2.png',grthresh)

# Find contours
im2, contours, hierarchy = cv2.findContours(grthresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)

# Look through contours, checking what we found
blob = 0
for i in range(len(contours)):
    area  = cv2.contourArea(contours[i])
    # Only consider ones taller than around 100 pixels and wider than about 300 pixels
    if area > 30000:
        # Get cropping box and crop
        rc = cv2.minAreaRect(contours[i])
        box = cv2.boxPoints(rc)
        Xs = [ box[0,0], box[1,0], box[2,0], box[3,0]]
        Ys = [ box[0,1], box[1,1], box[2,1], box[3,1]]
        x0 = int(round(min(Xs)))
        x1 = int(round(max(Xs)))
        y0 = int(round(min(Ys)))
        y1 = int(round(max(Ys)))
        cv2.imwrite(f'blob-{blob}.png', im[y0:y1,x0:x1])
        blob += 1

Это дает вам следующие файлы:

-rw-r--r--@ 1 mark  staff  248686  6 Jun 09:00 blob-0.png
-rw-r--r--@ 1 mark  staff   92451  6 Jun 09:00 blob-1.png
-rw-r--r--@ 1 mark  staff  101954  6 Jun 09:00 blob-2.png
-rw-r--r--@ 1 mark  staff  102373  6 Jun 09:00 blob-3.png
-rw-r--r--@ 1 mark  staff  633624  6 Jun 09:00 blob-4.png

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

Промежуточные файлы отладки: result-1.png:

enter image description here

А result-2.png:

enter image description here

...