Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用OpenCV从边缘图像中删除长水平/垂直线_Opencv_Image Processing - Fatal编程技术网

使用OpenCV从边缘图像中删除长水平/垂直线

使用OpenCV从边缘图像中删除长水平/垂直线,opencv,image-processing,Opencv,Image Processing,如何使用标准图像处理过滤器(来自OpenCV)从图像中删除长的水平线和垂直线 图像是黑白的,所以删除意味着简单地将其涂成黑色 说明: 我目前正在用Python做这件事,迭代像素行和列,检测连续像素的范围,删除超过N个像素的像素。但是,与OpenCV库相比,它的速度非常慢,如果有一种方法可以用OpenCV函数实现同样的功能,那么速度可能会快几个数量级 我想这可以通过使用一行像素(对于水平线)的内核进行卷积来实现,但我很难计算出实现这一技巧的确切操作。多长是“长”。长的行,例如,在整个图像的长度上

如何使用标准图像处理过滤器(来自OpenCV)从图像中删除长的水平线和垂直线

图像是黑白的,所以删除意味着简单地将其涂成黑色

说明:

我目前正在用Python做这件事,迭代像素行和列,检测连续像素的范围,删除超过N个像素的像素。但是,与OpenCV库相比,它的速度非常慢,如果有一种方法可以用OpenCV函数实现同样的功能,那么速度可能会快几个数量级

我想这可以通过使用一行像素(对于水平线)的内核进行卷积来实现,但我很难计算出实现这一技巧的确切操作。

多长是“长”。长的行,例如,在整个图像的长度上,或者仅仅比
n
像素长

如果是后者,那么您可以使用
n+1
X
n+1
中值或模式滤波器,并将角点系数设置为零,从而获得所需的效果

如果只是指整个图像宽度的行,只需对一行数据使用
memcmp()
函数,并将其与预先分配的与行长度相同的零数组进行比较。如果它们是相同的,您就知道您有一个横跨图像水平长度的空行,并且可以删除该行

这将比您当前使用的元素级比较快得多,这里对此进行了很好的解释:

如果要对垂直线重复相同的操作,只需转置图像,然后重复该操作


我知道这更像是一种系统优化级别的方法,而不是像您要求的那样使用openCV过滤器,但它可以快速、安全地完成工作。如果您设法强制映像和空数组在内存中32位对齐,则可以进一步加快计算速度。

如果您的行是真正水平/垂直的,请尝试此操作

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)    
结果


有关更多详细信息,请参阅文档

要从图像中删除水平线,可以使用边缘检测算法检测边缘,然后在OpenCV中使用Hough变换检测线条并将其涂成白色:

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)

这是针对javacv的

包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);

            }
    }
另一个

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);
    }
}

在这里快速思考。为什么不使用Hough直线检测来查找直线,并在选定的直线上执行所需操作?是的,即将发布相同的内容“查看”和“如果需要的话”。它似乎会返回拆分为许多小线段的长线段,这会破坏筛选出不够长线段的功能。。。知道为什么会这样吗?有人能向python解释linek=np.zeros((11,11),dtype=np.uint8)linek[5,…]=1的作用吗?C++优先;代码>材料线K=材料:零(尺寸(11,11),CV_8UC1);行(5)=255这有助于删除水平线。。。我还需要做哪些更改才能删除垂直线?只需添加
linek[…,5]=1
基本上创建一个
+
形状的内核第一个,您可以同时删除一幅图像中的垂直线和水平线。第二个选项,您可以分别删除一个图像中的垂直线和水平线,也就是说,您将得到一个没有垂直线或水平线的图像。@转到如果您没有检查我的代码,为什么单击“不喜欢”?