【问题标题】:How can i access the ordering of contours in `opencv`我如何访问`opencv`中的轮廓排序
【发布时间】:2018-07-04 21:05:43
【问题描述】:
import cv2
import Image
import numpy as np


#improve image..........................................................

im = cv2.imread('bw_image1.jpg') 
gray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray,(5,5),0)
thresh = cv2.adaptiveThreshold(blur,255,1,1,11,2)

contours,hierarchy = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
i=0
for cnt in contours:
     [x,y,w,h] = cv2.boundingRect(cnt)
     if h>15:
      cv2.rectangle(im,(x,y),(x+w,y+h),(0,0,255),1)
      im3=im[y:y+h,x:x+w]
      cv2.imwrite('objects/pix%i.png'%i,im3)
      i+=1
cv2.imshow('norm',im)
cv2.imwrite('objects/shhh.jpg',im)
key = cv2.waitKey(0)
#adding object............
im0 = cv2.imread('objects/pix0.png',0)
im1 = cv2.imread('objects/pix1.png',0)
im2 = cv2.imread('objects/pix2.png',0)
im3 = cv2.imread('objects/pix3.png',0)
im4 = cv2.imread('objects/pix4.png',0)
im5 = cv2.imread('objects/pix5.png',0)

h0, w0 = im0.shape[:2]
h1, w1 = im1.shape[:2]
h2, w2 = im2.shape[:2]
h3, w3 = im3.shape[:2]
h4, w4 = im4.shape[:2]
h5, w5 = im5.shape[:2]
maxh=max(h0,h1,h2,h3,h4,h5)

#add 50 for space between the objects

new = np.zeros((maxh, w0+w1+w2+w3+w4+w5+5),np.uint8)
new=(255-new)
new[maxh-h0:, :w0] = im0
new[maxh-h1:, w0+1:w0+w1+1] = im1
new[maxh-h2:, w0+w1+2:w0+w1+w2+2] = im2
new[maxh-h3:, w0+w1+w2+3:w0+w1+w2+w3+3] = im3
new[maxh-h4:, w0+w1+w2+w3+4:w0+w1+w2+w3+w4+4] = im4
new[maxh-h5:, w0+w1+w2+w3+w4+5:] = im5
gray = cv2.cvtColor(new, cv2.COLOR_GRAY2BGR)


cv2.imshow('norm',gray)
cv2.imwrite('objects/new_image.jpg',gray)
key = cv2.waitKey(0)
# threshold ................................................
im_gray = cv2.imread('objects/new_image.jpg', cv2.CV_LOAD_IMAGE_GRAYSCALE)

(thresh, im_bw) = cv2.threshold(im_gray, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
thresh = 20
im_bw = cv2.threshold(im_gray, thresh, 255, cv2.THRESH_BINARY)[1]
cv2.imwrite('bw_image1.jpg', im_bw)


im = Image.open('bw_image1.jpg')
im2 = im.resize((300, 175), Image.NEAREST)
im2.save('bw_image1.jpg')

我正在使用上面的代码重新排序图像

问题在于最终结果图像没有保存主图像的顺序

谁能告诉我怎么做?

主图:-

结果图片:-

主图像和结果图像单词应该看起来一样。提前致谢

【问题讨论】:

  • 它是否按从左到右的顺序查找轮廓?它可能只是随机订购它们。如果是这样,您可以通过边界矩形 x 值进行排序。
  • 随机排序,但我不知道如何以从左到右的顺序找到轮廓。你能告诉我怎么做吗? @无花果
  • 您可能无法更改它找到轮廓的顺序,但您可以对其进行排序。在您的情况下,您可能希望按每个边界矩形的 x 位置进行排序。您可以通过将每个边界矩形添加到列表中,按每个矩形的 x 位置排序,然后将图像写入文件来做到这一点。

标签: python python-2.7 numpy


【解决方案1】:

Opencv 从图像底部找到轮廓。所以当你试图找到这样的图像的轮廓时:

第一个轮廓是8(比3低一点)然后是3,7,9,4,e等高线的顺序。所以我们需要根据他们的x来存储对象,这个方法从左到右x已经增加了,所以我们可以使用下面的代码在find conturs之后存储创建的对象:

import numpy as np
import cv2

im = cv2.imread('nnn.jpg') 
gray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray,(5,5),0)
thresh = cv2.adaptiveThreshold(blur,255,1,1,19,4)

contours,hierarchy = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
h_list=[]
for cnt in contours:
     [x,y,w,h] = cv2.boundingRect(cnt)
    if w*h>250:
        h_list.append([x,y,w,h])
#print h_list          
ziped_list=zip(*h_list)
x_list=list(ziped_list[0])
dic=dict(zip(x_list,h_list))
x_list.sort()
i=0
for x in x_list:
      [x,y,w,h]=dic[x]
      #cv2.rectangle(im,(x,y),(x+w,y+h),(0,0,255),1)
      im3=im[y:y+h,x:x+w]
      cv2.imwrite('objects/pix%i.png'%i,im3)
      i+=1

      cv2.imshow('norm',im)
cv2.imwrite('objects/shhh.jpg',im)
key = cv2.waitKey(0)

注意#cv2.rectangle(im,(x,y),(x+w,y+h),(0,0,255),1) 行已被评论为拒绝结果图像中的额外行!

然后用这段代码连接保存的对象:

import numpy as np
import cv2

im0 = cv2.imread('objects/pix0.png',0)
im1 = cv2.imread('objects/pix1.png',0)
im2 = cv2.imread('objects/pix2.png',0)
im3 = cv2.imread('objects/pix3.png',0)
im4 = cv2.imread('objects/pix4.png',0)
im5 = cv2.imread('objects/pix5.png',0)

h0, w0 = im0.shape[:2]
h1, w1 = im1.shape[:2]
h2, w2 = im2.shape[:2]
h3, w3 = im3.shape[:2]
h4, w4 = im4.shape[:2]
h5, w5 = im5.shape[:2]
maxh=max(h0,h1,h2,h3,h4,h5)

#add 50 for space between the objects

new = np.zeros((maxh, w0+w1+w2+w3+w4+w5+50),np.uint8)
new=(255-new)
new[maxh-h0:, :w0] = im0
new[maxh-h1:, w0+10:w0+w1+10] = im1
new[maxh-h2:, w0+w1+20:w0+w1+w2+20] = im2
new[maxh-h3:, w0+w1+w2+30:w0+w1+w2+w3+30] = im3
new[maxh-h4:, w0+w1+w2+w3+40:w0+w1+w2+w3+w4+40] = im4
new[maxh-h5:, w0+w1+w2+w3+w4+50:] = im5
gray = cv2.cvtColor(new, cv2.COLOR_GRAY2BGR)


cv2.imshow('norm',gray)
cv2.imwrite('objects/new_image.jpg',gray)
key = cv2.waitKey(0)

结果:

【讨论】:

  • 您好,这段代码标记为 5 bx 而不是三个 :'( @Kasra
  • 我可以给你一些文字图片你可以运行程序吗?它给出了答案@kara
  • 正如我所说的,如果你能正确提取轮廓,你就可以做到这一点
  • 每个零检测零内和零外的两个框元素。如果我增加 h 的值,那么后面的小 c 和 a 就不会被检测到。如果在一个维度上检测到两个元素,那么是否必须选择更大的一个?添加条件?那么所有的代码将是 100% 完美的。 @kasra
  • 我已经更正了代码。在线编辑: thresh = cv2.adaptiveThreshold(blur,255,1,1,19,4) 并从仅高度到区域选择矩形:D。请投票赞成我的问题,我正在投票赞成你的答案。 @kasra
【解决方案2】:
import cv2
import numpy as np

im = cv2.imread('0.jpg')
gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (5, 5), 0)
thresh = cv2.adaptiveThreshold(blur, 255, 1, 1, 11, 2)

_, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
i = 0
for cnt in contours:
    [x, y, w, h] = cv2.boundingRect(cnt)
    if h > 15:
        cv2.rectangle(im, (x, y), (x + w, y + h), (0, 0, 255), 1)
        im3 = im[y:y + h, x:x + w]
        cv2.imwrite('ob/pix%i.png' % i, im3)
        i += 1
cv2.imshow('norm', im)
key = cv2.waitKey(0)

【讨论】:

    猜你喜欢
    • 2021-09-14
    • 2013-05-29
    • 2017-01-17
    • 1970-01-01
    • 2012-11-09
    • 1970-01-01
    • 2021-05-08
    • 2015-12-16
    • 1970-01-01
    相关资源
    最近更新 更多