Python 如何从图像中提取图表?
我使用了基于轮廓的方法,但是它检测了太多的轮廓。如何提取ROI轮廓Python 如何从图像中提取图表?,python,opencv,image-processing,computer-vision,ocr,Python,Opencv,Image Processing,Computer Vision,Ocr,我使用了基于轮廓的方法,但是它检测了太多的轮廓。如何提取ROI轮廓 image = cv2.imread('ULTI.png') original = image.copy() cv2.imwrite("bg.png",bg) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) blurred = cv2.GaussianBlur(gray, (3, 3), 0) canny = cv2.Canny(blurred, 120, 255
image = cv2.imread('ULTI.png')
original = image.copy()
cv2.imwrite("bg.png",bg)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (3, 3), 0)
canny = cv2.Canny(blurred, 120, 255, 1)
kernel = np.ones((5,5),np.uint8)
dilate = cv2.dilate(canny, kernel, iterations=1)
# Find contours
cnts = cv2.findContours(dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
# Iterate thorugh contours and filter for ROI
image_number = 0
cnts = max(cnts, key = cv2.contourArea)
print("no ",len(cnts))
for c in cnts:
x,y,w,h = cv2.boundingRect(c)
cv2.rectangle(image, (x, y), (x + w, y + h), (36,255,12), 2)
ROI = original[y:y+h, x:x+w]
#cv2.imwrite("ROI_{}.png".format(image_number), ROI)
image_number += 1
您可以通过指定只希望使用具有最大面积的轮廓来获得ROI,也就是说,如果图表生成的轮廓的面积大于图像中其他组件的面积,则可以获得ROI 以下是一个例子:
import cv2
def preprocess(img):
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img_blur = cv2.GaussianBlur(img_gray, (5, 5), 1)
img_canny = cv2.Canny(img_blur, 50, 50)
return img_canny
def get_roi(img, pad=3):
contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
max_area = 0
for cnt in contours:
peri = cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, 0.02 * peri, True)
x, y, w, h = cv2.boundingRect(approx)
rect_area = w * h
if rect_area > max_area:
max_area = rect_area
dim = x, y, w, h
if max_area:
x, y, w, h = dim
return x - pad, y - pad, w + pad * 2, h + pad * 2
img = cv2.imread("ULTI.png")
img_processed = preprocess(img)
x, y, w, h = get_roi(img_processed)
cv2.imshow("Image", img[y:y + h, x:x + w])
cv2.waitKey(0)
输出:
说明:
for
循环在轮廓中循环,并找到循环每次迭代的轮廓区域:if
语句检查面积是否大于应存储该最大面积的定义变量。如果该迭代轮廓的面积大于该变量,则更新该变量的值,使其等于新区域。此外,将该迭代的轮廓保存到变量:for
循环之后,如果max\u area
变量不等于0
,则还定义了max\u cnt
。使用cv2.boundingRect
获取x
、y
、w
和h
属性:preprocess
函数中的值以满足您的需要
import cv2
def preprocess(img):
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img_blur = cv2.GaussianBlur(img_gray, (5, 5), 1)
img_canny = cv2.Canny(img_blur, 50, 50)
return img_canny
def get_roi(img, pad=3):
contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
max_area = 0
for cnt in contours:
peri = cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, 0.02 * peri, True)
area = cv2.contourArea(approx)
if area > max_area:
max_area = area
max_cnt = approx
if max_area:
x, y, w, h = cv2.boundingRect(max_cnt)
return x - pad, y - pad, w + pad * 2, h + pad * 2
img = cv2.imread("ULTI.png")
img_processed = preprocess(img)
x, y, w, h = get_roi(img_processed)
cv2.imshow("Image", img[y:y + h, x:x + w])
cv2.waitKey(0)