Opencv ile test sorusu çıkarma

Merhaba.

Tresh uyguladığımızdaki görüntü.

Aşağıda dilate ettiğimizdeki görüntü.

Image ile pargrafları yakaladığımızda gördüğümüz kod.

Buraya yukarıdaki sonuçları çıkaran kodu bırakayım:

import cv2
import numpy as np

image = cv2.imread('test.jpeg')

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (7,7), 0)
thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

# Create rectangular structuring element and dilate
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
dilate = cv2.dilate(thresh, kernel, iterations=3)

# Find contours and draw rectangle
cnts = cv2.findContours(dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

for c in cnts:
    x,y,w,h = cv2.boundingRect(c)
    
    if w>40 : # Except thin lines
        cv2.rectangle(image, (x, y), (x + w, y + h), (36,255,12), 2)
        print(y,h)
# Resize Image For My Screen Resoulation. Remove befor run.        
thresh = cv2.resize(thresh, (0, 0), fx = 0.7, fy = 0.7) 
dilate = cv2.resize(dilate, (0, 0), fx = 0.7, fy = 0.7)
image = cv2.resize(image, (0, 0), fx = 0.7, fy = 0.7)

cv2.imshow('thresh', thresh)
cv2.imshow('dilate', dilate)
cv2.imshow('image', image)
cv2.waitKey()

Siz neyi paragraf olarak buldurmak isterseniz o kadarını paragraf olarak bulabilir kod.

 if w>40 : # Except thin lines
        cv2.rectangle(image, (x, y), (x + w, y + h), (36,255,12), 2)
        print(y,h)

Bu kısımda belirli bir genişliğin altındaki paragrafları görmezden gel demi oluyoruz. Deneme yanılma ile 40 vererek soru numaralarını hariç tuttum. Tarayacağınız dokümanda bu değerler değişebilir. Kendinize göre ayarlamalısınız. Çok büyük bir rakam kullanır ve şıkların genişliğine denk gelirse şıkları çerçeveleyemeybilirsiniz. Buradaki değerle oynayarak uygun değerleri bulabilirsiniz.

Gelelim bunun şıklarla ilintilenmesine;

Şimdi kodun içinde bir satır değiştireceğim. Sonuçlara beraber bakalım.

Tresh Değeri:

Dilate Değeri:

Image Sonuç:

Dikkat ettiyseniz bir önceki dilate görüntüsü ile sonraki değişmiş durumda.

Bu değişiklik şıklar ile soruyu bir biri ile dikey daha yaklaştırıyor.

Yani;

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,20))

satırında sadece, MORPH_RECT, değerinden sonra (5,5) yerine (5,20) verdim böylece, Y yönünde bir birleşme sağladım.

Tabi bu değerler bendeki resim üzeriden siz kendi resimleriniz için bunları deneyerek görerek ayarlamalısınız.

Bu durumda kodumız:

import cv2
import numpy as np

image = cv2.imread('test.jpeg')

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (7,7), 0)
thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

# Create rectangular structuring element and dilate
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,20))
dilate = cv2.dilate(thresh, kernel, iterations=3)

# Find contours and draw rectangle
cnts = cv2.findContours(dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

for c in cnts:
    x,y,w,h = cv2.boundingRect(c)
    
    if w>40 : # Except thin lines
        cv2.rectangle(image, (x, y), (x + w, y + h), (36,255,12), 2)
        print(y,h)
# Resize Image For My Screen Resoulation. Remove befor run.        
thresh = cv2.resize(thresh, (0, 0), fx = 0.7, fy = 0.7) 
dilate = cv2.resize(dilate, (0, 0), fx = 0.7, fy = 0.7)
image = cv2.resize(image, (0, 0), fx = 0.7, fy = 0.7)

cv2.imshow('thresh', thresh)
cv2.imshow('dilate', dilate)
cv2.imshow('image', image)
cv2.waitKey()

Şekline gelir.

# Resize Image For My Screen Resoulation. Remove befor run.        
thresh = cv2.resize(thresh, (0, 0), fx = 0.7, fy = 0.7) 
dilate = cv2.resize(dilate, (0, 0), fx = 0.7, fy = 0.7)
image = cv2.resize(image, (0, 0), fx = 0.7, fy = 0.7)

satırları ile görüntüyü %70’e ölçekledim. Ekran alıntısı yaparken tamamı ekranda biraz küçülsün diye, bu kod satırlarını kendi kodunuzda kaldırabilirsiniz.

Gelelim sizin kodunuza.

Yukarıda anlattığım üzere minik bir oynama gerekiyor.

Burada yine deneme yanılma ile;

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 15))

(5,5) değerini (5,15) olarak değiştirdim.

Sizde yine kullanacağınız görüntüye gere bu değerler değişebilir. Çünkü soruların aralıkları şıkların mesafeleri sorudan soruya değişebilir. Bunları ilk verdiğim kod üzerinde görsel görerek düzenleyebilir. Yada deneme yanılma bulabilirsiniz.

Kodunuzun değiştirilmiş hali:

import cv2

class DrawRectangel:

    def DrawRects(self,image_path,iter):
        # Load image, grayscale, Gaussian blur, Otsu's threshold
        image = cv2.imread(image_path)
        cnts = self.findConturs(image,iter)
        image2 = image.copy()

        for c in cnts:
            x, y, w, h = cv2.boundingRect(c)
            if image2.shape[1] // 4 < w < image2.shape[1] // 2 :
                cv2.rectangle(image2, (x, y),(x + w , y + h), (0, 0, 255),1)

        cv2.imshow('Paragarflar',image2)
        cv2.waitKey(0)
        cv2.destroyAllWindows()


    def findConturs(self,image,iter):
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        blur = cv2.GaussianBlur(gray, (7, 7), 0)
        thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

        # Create rectangular structuring element and dilate
        kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 15))
        dilate = cv2.dilate(thresh, kernel, iterations=iter)

        # Find contours and draw rectangle
        cnts = cv2.findContours(dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
        cnts = cnts[0] if len(cnts) == 2 else cnts[1]

        return cnts

DrawRectangel().DrawRects("test.jpeg",4)

Not: Sizin resmi test.jpg olarak kaydedip kullandım.

İlgili kodlarda kullanacağınız resme göre bu kısımları değiştirebilirsiniz.

2 Beğeni