Suppression de longues lignes horizontales/verticales de l'image de bord à L'aide D'OpenCV

Comment puis-je utiliser les filtres de traitement d'image standard (D'OpenCV) pour supprimer les longues lignes horizontales et verticales d'une image?

les images sont en noir et blanc donc enlever signifie simplement peindre en noir.

à titre d'Illustration:

illustration of required filter

je le fais actuellement en Python, en itérant sur les lignes de pixels et les cols et en détectant les plages de pixels consécutifs, en supprimant ceux qui sont plus longs que N Pixel. Cependant, il est vraiment lent par rapport à la bibliothèque OpenCV, et s'il y a un moyen d'accomplir la même chose avec les fonctions OpenCV, ce sera probablement des ordres de grandeur plus rapide.

j'imagine que cela peut être fait par convolution en utilisant un noyau qui est une rangée de pixels (pour les lignes horizontales), mais j'ai du mal à comprendre l'opération exacte qui ferait l'affaire.

5
demandé sur Assaf Lavie 2013-09-30 16:45:20

5 réponses

si vos lignes sont vraiment horizontales / verticales, essayez

import cv2
import numpy as np
img = cv2.imread('c:/data/test.png')
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
linek = np.zeros((11,11),dtype=np.uint8)
linek[5,...]=1
x=cv2.morphologyEx(gray, cv2.MORPH_OPEN, linek ,iterations=1)
gray-=x
cv2.imshow('gray',gray)
cv2.waitKey(0)    

résultat

enter image description here

vous pouvez Vous référer OpenCV Transformations Morphologiques documentation pour plus de détails.

6
répondu Zaw Lin 2018-09-20 01:31:33

Combien de temps est "long". Long, comme dans, les lignes qui courent la longueur de l'image entière, ou juste plus long que n pixels?

si ce dernier, alors vous pouvez juste utiliser un n+1 x n+1 filtre médian ou de mode, et de définir les coefficients de coin à zéro, et vous obtiendriez l'effet désiré.

si vous faites référence à juste des lignes qui exécutent la largeur de l'image entière, il suffit d'utiliser la fonction memcmp() contre une rangée de données, et le comparer à un pré-alloués tableau de zéros qui est de la même longueur d'une ligne. Si elles sont identiques, vous savez que vous avez une ligne blanche qui s'étend sur la longueur horizontale de l'image, et cette ligne peut être supprimée.

ce sera beaucoup plus rapide que les comparaisons par éléments que vous utilisez actuellement, et est très bien expliqué ici:

pourquoi memcpy() et memmove() sont-ils plus rapides que les incréments de pointeur?

Si vous souhaitez répéter la même opération pour les lignes verticales, juste transposer l'image, et répétez l'opération.

je sais que c'est plus une approche au niveau de l'optimisation du système qu'un filtre openCV comme vous l'avez demandé, mais cela permet de faire le travail rapidement et en toute sécurité. Vous pouvez accélérer le calcul encore plus si vous parvenez à forcer l'image et votre tableau vide à être aligné sur 32 bits en mémoire.

1
répondu DevNull 2017-05-23 12:25:12

pour supprimer les lignes horizontales d'une image, vous pouvez utiliser un algorithme de détection de bord pour détecter les bords et ensuite utiliser la Transformée de Hough dans OpenCV pour détecter les lignes et les colorier en blanc:

import cv2
import numpy as np
img = cv2.imread(img,0)
laplacian = cv2.Laplacian(img,cv2.CV_8UC1) # Laplacian Edge Detection
minLineLength = 900
maxLineGap = 100
lines = cv2.HoughLinesP(laplacian,1,np.pi/180,100,minLineLength,maxLineGap)
for line in lines:
    for x1,y1,x2,y2 in line:
        cv2.line(img,(x1,y1),(x2,y2),(255,255,255),1)
cv2.imwrite('Written_Back_Results.jpg',img)
0
répondu Anindita Bhowmik 2016-07-13 11:43:21

c'est pour javacv.

package com.test11;

import org.opencv.core.*;
import org.opencv.imgproc.Imgproc;
import org.opencv.imgcodecs.Imgcodecs;

public class GetVerticalOrHorizonalLines {

    static{ System.loadLibrary(Core.NATIVE_LIBRARY_NAME); }

    public static void main(String[] args) {

        //Canny process before HoughLine Recognition

        Mat source = Imgcodecs.imread("src//data//bill.jpg");
        Mat gray = new Mat(source.rows(),source.cols(),CvType.CV_8UC1);
        Imgproc.cvtColor(source, gray, Imgproc.COLOR_BGR2GRAY);

        Mat binary = new Mat();
        Imgproc.adaptiveThreshold(gray, binary, 255, Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY, 15, -2);
        Imgcodecs.imwrite("src//data//binary.jpg", binary);

        Mat horizontal = binary.clone();
        int horizontalsize = horizontal.cols() / 30;
        int verticalsize = horizontal.rows() / 30;

        Mat horizontal_element = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(horizontalsize,1));
        //Mat element = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(3,3));
        Imgcodecs.imwrite("src//data//horizontal_element.jpg", horizontal_element);

        Mat Linek = Mat.zeros(source.size(), CvType.CV_8UC1);
        //x =  Imgproc.morphologyEx(gray, dst, op, kernel, anchor, iterations);
        Imgproc.morphologyEx(gray, Linek,Imgproc.MORPH_BLACKHAT, horizontal_element);
        Imgcodecs.imwrite("src//data//bill_RECT_Blackhat.jpg", Linek);

        Mat vertical_element = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(1,verticalsize));
        Imgcodecs.imwrite("src//data//vertical_element.jpg", vertical_element);

        Mat Linek2 = Mat.zeros(source.size(), CvType.CV_8UC1);
        //x =  Imgproc.morphologyEx(gray, dst, op, kernel, anchor, iterations);
        Imgproc.morphologyEx(gray, Linek2,Imgproc.MORPH_CLOSE, vertical_element);
        Imgcodecs.imwrite("src//data//bill_RECT_Blackhat2.jpg", Linek2);

            }
    }
-1
répondu Anton KONG 2017-03-02 07:05:39

un autre.

package com.test12;

import org.opencv.core.*;
import org.opencv.imgproc.Imgproc;
import org.opencv.imgcodecs.Imgcodecs;

public class ImageSubstrate {

    static{ System.loadLibrary(Core.NATIVE_LIBRARY_NAME); }

    public static void main(String[] args) {

           Mat source = Imgcodecs.imread("src//data//bill.jpg");

           Mat image_h = Mat.zeros(source.size(), CvType.CV_8UC1);
           Mat image_v = Mat.zeros(source.size(), CvType.CV_8UC1); 

           Mat output = new Mat();
           Core.bitwise_not(source, output);
           Mat output_result = new Mat();

           Mat kernel_h = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(20, 1));
           Imgproc.morphologyEx(output, image_h, Imgproc.MORPH_OPEN, kernel_h);
           Imgcodecs.imwrite("src//data//output.jpg", output);  

           Core.subtract(output, image_h, output_result);
           Imgcodecs.imwrite("src//data//output_result.jpg", output_result);    


           Mat kernel_v = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(1, 20));   
           Imgproc.morphologyEx(output_result, image_v, Imgproc.MORPH_OPEN, kernel_v);
           Mat output_result2 = new Mat();

           Core.subtract(output_result, image_v, output_result2);          
           Imgcodecs.imwrite("src//data//output_result2.jpg", output_result2);
    }
}
-1
répondu Anton KONG 2017-03-02 07:11:08