【问题标题】:Crop out part from images (findContours?) {opencv, java}从图像中裁剪出部分(findContours?){opencv,java}
【发布时间】:2014-06-01 19:02:38
【问题描述】:

我有这张图片,里面有包含字母的盒子,像这样:

我已经能够裁剪出每个框。像这样:

现在我的问题。我怎样才能只从每个框中裁剪出字母?想要的结果是这样的

我想使用 findContours,但我不确定如何实现这一点,因为它会检测噪音和周围的一切。

【问题讨论】:

  • 这里是一个快速浏览。我看到在你所有的情况下,所需的图像都在中心。有变化吗?如果没有,您可以从边界移除图像的四分之一部分并保留中心部分。如果您的案例比较多样化,请在一般案例上稍加说明以正确理解问题。
  • 没有变化,字母总是在方框的中心,但是方框会出现在不同的地方。
  • Ruzzle 上作弊? :-)
  • 哈哈,是的,创造一个会玩拼图的乐高机器人:)

标签: java opencv crop


【解决方案1】:

接近 根据这个事实,我建议您采用以下方法,您可以提取框。如果您按照步骤提供该框,我认为这会起作用:

  1. 找到图像的中心
  2. 找到图像中的轮廓 - 可以是候选者
  3. 找到每个轮廓的边界矩形
  4. 找到每个边界矩形的中心
  5. 找出每个边界矩形到图像中心的距离
  6. 找到最小距离 - 你的答案

注意:有一个名为pad 的变量控制结果图形的填充! 对你所有的盒子都这样做。我希望这会有所帮助!

祝你好运:)


Python 代码

# reading image in grayscale
image = cv2.imread('testing2.jpg',cv2.CV_LOAD_IMAGE_GRAYSCALE)
# thresholding to get a binary one
ret, image = cv2.threshold(image, 100,255,cv2.THRESH_BINARY_INV)
# finding the center of image
image_center = (image.shape[0]/2, image.shape[1]/2)

if image is None:
    print 'can not read the image data'
# finding image contours
contours, hier = cv2.findContours(image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# finding distance of each contour from the center of image
d_min = 1000
for contour in contours:
    # finding bounding rect
    rect = cv2.boundingRect(contour)
    # skipping the outliers
    if rect[3] > image.shape[1]/2 and rect[2] > image.shape[0]/2:
        continue
    pt1 = (rect[0], rect[1])
    # finding the center of bounding rect-digit
    c = (rect[0]+rect[2]*1/2, rect[1]+rect[3]*1/2)
    d = np.sqrt((c[0] - image_center[0])**2 + (c[1]-image_center[1])**2)
    # finding the minimum distance from the center
    if d < d_min:
        d_min = d
        rect_min = [pt1, (rect[2],rect[3])]
# fetching the image with desired padding
pad = 5
result = image[rect_min[0][1]-pad:rect_min[0][1]+rect_min[1][1]+pad, rect_min[0][0]-pad:rect_min[0][0]+rect_min[1][0]+pad]

plt.imshow(result*255, 'gray')
plt.show()

Java 代码

    System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    // reading image 
    Mat image = Highgui.imread(".\\testing2.jpg", Highgui.CV_LOAD_IMAGE_GRAYSCALE);
    // clone the image 
    Mat original = image.clone();
    // thresholding the image to make a binary image
    Imgproc.threshold(image, image, 100, 128, Imgproc.THRESH_BINARY_INV);
    // find the center of the image
    double[] centers = {(double)image.width()/2, (double)image.height()/2};
    Point image_center = new Point(centers);

    // finding the contours
    ArrayList<MatOfPoint> contours = new ArrayList<MatOfPoint>();
    Mat hierarchy = new Mat();
    Imgproc.findContours(image, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);

    // finding best bounding rectangle for a contour whose distance is closer to the image center that other ones
    double d_min = Double.MAX_VALUE;
    Rect rect_min = new Rect();
    for (MatOfPoint contour : contours) {
        Rect rec = Imgproc.boundingRect(contour);
        // find the best candidates
        if (rec.height > image.height()/2 & rec.width > image.width()/2)            
            continue;
        Point pt1 = new Point((double)rec.x, (double)rec.y);
        Point center = new Point(rec.x+(double)(rec.width)/2, rec.y + (double)(rec.height)/2);
        double d = Math.sqrt(Math.pow((double)(pt1.x-image_center.x),2) + Math.pow((double)(pt1.y -image_center.y), 2));            
        if (d < d_min)
        {
            d_min = d;
            rect_min = rec;
        }                   
    }
    // slicing the image for result region
    int pad = 5;        
    rect_min.x = rect_min.x - pad;
    rect_min.y = rect_min.y - pad;

    rect_min.width = rect_min.width + 2*pad;
    rect_min.height = rect_min.height + 2*pad;

    Mat result = original.submat(rect_min);     
    Highgui.imwrite("result.png", result);

编辑: 已添加 Java 代码!

结果

【讨论】:

  • 看起来很不错,能否提供java代码,非常感谢!因为现在 python(?) 和 java 之间存在一些差异,以及一些我真的不知道如何在 java 中执行的函数
  • 我几乎用过opencv函数。你能告诉我哪些台词对你来说很陌生吗?!
  • 我会先尝试在java中制作它,如果我有其他问题我会回来:)
  • 干杯伙伴!很棒的帖子。
猜你喜欢
  • 1970-01-01
  • 2012-12-31
  • 1970-01-01
  • 1970-01-01
  • 2018-01-08
  • 1970-01-01
  • 2017-08-04
  • 2023-03-05
  • 2020-09-07
相关资源
最近更新 更多