如何在 python 中对图像中的感兴趣区域执行自动检测和裁剪?
How to perform automated detection and cropping of region of interest in an image in python?
我想对我感兴趣的区域执行操作..也就是您可以在图像中看到的中央矩形 table。
我可以手动给出感兴趣区域的坐标并裁剪该部分
img = cv2.imread('test12.jpg',0)
box = img[753:1915,460:1315]
但我想在不提供像素或坐标的情况下自动裁剪该部分manually.Can谁能帮我解决这个问题?
http://picpaste.com/test12_-_Copy-BXqHMAnd.jpg这是我的原图。
http://picpaste.com/boxdemo-zHz57dBM.jpg 这是我裁剪后的图片。
为此,我输入了所需区域的坐标并进行了裁剪。
但是,现在我必须处理许多相似的图像,其中我感兴趣的区域的坐标会略有不同。我想要一种方法来检测 table(我感兴趣的区域)并裁剪它。
目前我正在使用这个
img = cv2.imread('test12.jpg',0)
box = img[753:1915,460:1315]
裁剪我的形象。
您可以尝试使用 openCV 模板匹配来查找图像中矩形 table 的坐标。
Template Matching
以下是一个测试程序,用于查找我要查找的图像的坐标。
from __future__ import print_function
import cv2
import numpy as np
from matplotlib import pyplot as plt
try:
img = cv2.imread(r'new_webcam_image.jpg',0)
template = cv2.imread(r'table_template.jpg',0)
except IOError as e:
print("({})".format(e))
else:
img2 = img.copy()
w, h = template.shape[::-1]
# All the 6 methods for comparison in a list
methods = ['cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCORR',
'cv2.TM_CCORR_NORMED', 'cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED']
for meth in methods:
img = img2.copy()
method = eval(meth)
# Apply template Matching
res = cv2.matchTemplate(img,template,method)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
print("Method: %s" , meth)
print("min_val: " , min_val)
print("max_val: " , max_val)
print("min_loc: " , min_loc)
print("max_loc: " , max_loc)
print(" ")
# If the method is TM_SQDIFF or TM_SQDIFF_NORMED, take minimum
if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
top_left = min_loc
else:
top_left = max_loc
bottom_right = (top_left[0] + w, top_left[1] + h)
cv2.rectangle(img,top_left, bottom_right, 255, 2)
plt.subplot(121),plt.imshow(res,cmap = 'gray')
plt.title('Matching Result'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(img,cmap = 'gray')
plt.title('Detected Point'), plt.xticks([]), plt.yticks([])
plt.suptitle(meth) #; plt.legend([min_val, max_val, min_loc, max_loc], ["min_val", "max_val", "min_loc", "max_loc"])
plt.show()
box = img[top_left[1]:top_left[1]+h,0:bottom_right[1]+w]
cv2.imshow("cropped", box)
cv2.waitKey(0)
我没有适合您的完整解决方案。显示的代码基于我用来修复扫描仪输出的一些代码。对我来说,模板解决方案听起来是一种更好的方法,但下面的内容应该会给你一些其他的东西。
import cv2
imageSrc = cv2.imread("test12.jpg")
# First cut the source down slightly
h = imageSrc.shape[0]
w = imageSrc.shape[1]
cropInitial = 50
imageSrc = imageSrc[100:50+(h-cropInitial*2), 50:50+(w-cropInitial*2)]
# Threshold the image and find edges (to reduce the amount of pixels to count)
ret, imageDest = cv2.threshold(imageSrc, 220, 255, cv2.THRESH_BINARY_INV)
imageDest = cv2.Canny(imageDest, 100, 100, 3)
# Create a list of remaining pixels
points = cv2.findNonZero(imageDest)
# Calculate a bounding rectangle for these points
hull = cv2.convexHull(points)
x,y,w,h = cv2.boundingRect(hull)
# Crop the original image to the bounding rectangle
imageResult = imageSrc[y:y+h,x:x+w]
cv2.imwrite("test12 cropped.jpg", imageResult)
输出没有按照您的需要裁剪。使用各种阈值参数应该会改善您的结果。
我建议在 imageThresh
和 imageDest
的不同位置使用 imshow
,这样您就可以看到代码中每个阶段发生了什么。希望这能帮助你进步。
我想对我感兴趣的区域执行操作..也就是您可以在图像中看到的中央矩形 table。
我可以手动给出感兴趣区域的坐标并裁剪该部分
img = cv2.imread('test12.jpg',0)
box = img[753:1915,460:1315]
但我想在不提供像素或坐标的情况下自动裁剪该部分manually.Can谁能帮我解决这个问题?
http://picpaste.com/test12_-_Copy-BXqHMAnd.jpg这是我的原图。
http://picpaste.com/boxdemo-zHz57dBM.jpg 这是我裁剪后的图片。
为此,我输入了所需区域的坐标并进行了裁剪。
但是,现在我必须处理许多相似的图像,其中我感兴趣的区域的坐标会略有不同。我想要一种方法来检测 table(我感兴趣的区域)并裁剪它。
目前我正在使用这个
img = cv2.imread('test12.jpg',0)
box = img[753:1915,460:1315]
裁剪我的形象。
您可以尝试使用 openCV 模板匹配来查找图像中矩形 table 的坐标。 Template Matching
以下是一个测试程序,用于查找我要查找的图像的坐标。
from __future__ import print_function
import cv2
import numpy as np
from matplotlib import pyplot as plt
try:
img = cv2.imread(r'new_webcam_image.jpg',0)
template = cv2.imread(r'table_template.jpg',0)
except IOError as e:
print("({})".format(e))
else:
img2 = img.copy()
w, h = template.shape[::-1]
# All the 6 methods for comparison in a list
methods = ['cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCORR',
'cv2.TM_CCORR_NORMED', 'cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED']
for meth in methods:
img = img2.copy()
method = eval(meth)
# Apply template Matching
res = cv2.matchTemplate(img,template,method)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
print("Method: %s" , meth)
print("min_val: " , min_val)
print("max_val: " , max_val)
print("min_loc: " , min_loc)
print("max_loc: " , max_loc)
print(" ")
# If the method is TM_SQDIFF or TM_SQDIFF_NORMED, take minimum
if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
top_left = min_loc
else:
top_left = max_loc
bottom_right = (top_left[0] + w, top_left[1] + h)
cv2.rectangle(img,top_left, bottom_right, 255, 2)
plt.subplot(121),plt.imshow(res,cmap = 'gray')
plt.title('Matching Result'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(img,cmap = 'gray')
plt.title('Detected Point'), plt.xticks([]), plt.yticks([])
plt.suptitle(meth) #; plt.legend([min_val, max_val, min_loc, max_loc], ["min_val", "max_val", "min_loc", "max_loc"])
plt.show()
box = img[top_left[1]:top_left[1]+h,0:bottom_right[1]+w]
cv2.imshow("cropped", box)
cv2.waitKey(0)
我没有适合您的完整解决方案。显示的代码基于我用来修复扫描仪输出的一些代码。对我来说,模板解决方案听起来是一种更好的方法,但下面的内容应该会给你一些其他的东西。
import cv2
imageSrc = cv2.imread("test12.jpg")
# First cut the source down slightly
h = imageSrc.shape[0]
w = imageSrc.shape[1]
cropInitial = 50
imageSrc = imageSrc[100:50+(h-cropInitial*2), 50:50+(w-cropInitial*2)]
# Threshold the image and find edges (to reduce the amount of pixels to count)
ret, imageDest = cv2.threshold(imageSrc, 220, 255, cv2.THRESH_BINARY_INV)
imageDest = cv2.Canny(imageDest, 100, 100, 3)
# Create a list of remaining pixels
points = cv2.findNonZero(imageDest)
# Calculate a bounding rectangle for these points
hull = cv2.convexHull(points)
x,y,w,h = cv2.boundingRect(hull)
# Crop the original image to the bounding rectangle
imageResult = imageSrc[y:y+h,x:x+w]
cv2.imwrite("test12 cropped.jpg", imageResult)
输出没有按照您的需要裁剪。使用各种阈值参数应该会改善您的结果。
我建议在 imageThresh
和 imageDest
的不同位置使用 imshow
,这样您就可以看到代码中每个阶段发生了什么。希望这能帮助你进步。