文章目录
前言
对图片中的多个目标要进行分割,并且已知各个目标的多个点坐标,各个坐标存储在json文件中。考虑到的问题是目前快速切割图片的方法几乎都是矩形式分割,故要针对矩形四个点来进行,对于多边形目标,首先要找到能包含它们的矩阵。
一、使用步骤
1.首先要从json文件中获取到各个目标的坐标点
代码如下(示例):
with open(os.path.join(json_path,json_files), "r") as in_file:
json_dict=json.load(in_file)
# print(json_dict) #这里的json_dict就完全是一个字典了
for shapes in json_dict["shapes"]:
label=shapes["label"] # 获得标签
points=shapes['points'] # 获得坐标点
2.使用cv2.minAreaRect()和cv2.boxPoints()获得最小外接矩阵的四个顶点
代码如下(示例):
points = np.float32(np.array(points)) #接收类型要转变
'''
cv2.minAreaRect(Points),其中points是点集,数据类型为ndarray,array((x1,y1),(x2,y2),....,(xn,yn))
返回一种叫Box2d的结构,如((81.0,288),(22.0,10.0),-0.0),分别表示(中心点坐标,(宽度,高度),旋转的角度)
'''
rect = cv2.minAreaRect(points) # 得到最小外接矩形的(中心(x,y), (宽,高), 旋转角度)
box = np.int0(cv2.boxPoints(rect)) # 获取最小外接矩形的4个顶点坐标,np.int0表示取整(ps: cv2.boxPoints(rect) for OpenCV 3.x)
3.根据四个顶点来裁剪图片
代码如下(示例):
xs = [j[0] for j in box] # 获得4个点的横坐标
ys = [j[1] for j in box] # 获得4个点的纵坐标
x1 = min(xs)
x2 = max(xs)
y1 = min(ys)
y2 = max(ys)
if x1 < 0:
x1 = 0
if x2 > image_col:
x2 = image_col
if y1 < 0:
y1 = 0
if y2 > image_row:
y2 = image_row
hight = y2 - y1
width = x2 - x1
# print(x1, x2, y1, y2)
cropimage = image[y1:y2, x1:x2]
总结
完整代码如下(示例):
import json
import cv2
import numpy as np
import os
import math
import tqdm
image_path = 'F:\\xxxxxx'
image_total = []
images_file = os.listdir(image_path)
for image_file in images_file: # 获得每张图片名
first,last = os.path.splitext(image_file) # 分开后缀名
image_total.append(first)
for img in image_total:
filename_img = img+'.jpg'
path = os.path.join(image_path,filename_img)
image = cv2.imread(path)
shape = image.shape
image_row = shape[0]
image_col = shape[1]
json_files = 'D:\\xxxx.json'
boxs=[]
n=1
with open(json_files, "r") as in_file:
json_dict=json.load(in_file)
# print(json_dict) #这里的json_dict就是完全是一个字典了
for shapes in json_dict["shapes"]:
label=shapes["label"]
# print(type(shapes))
points=shapes['points']
points = np.float32(np.array(points))
# print(type(points))
rect = cv2.minAreaRect(points) # 得到最小外接矩形的(中心(x,y), (宽,高), 旋转角度)
box = np.int0(cv2.boxPoints(rect)) # 获取最小外接矩形的4个顶点坐标(ps: cv2.boxPoints(rect) for OpenCV 3.x)
xs = [j[0] for j in box] # 获得4个点的横坐标
ys = [j[1] for j in box] # 获得4个点的纵坐标
x1 = min(xs)
x2 = max(xs)
y1 = min(ys)
y2 = max(ys)
if x1 < 0:
x1 = 0
if x2 > image_col:
x2 = image_col
if y1 < 0:
y1 = 0
if y2 > image_row:
y2 = image_row
hight = y2 - y1
width = x2 - x1
# print(x1, x2, y1, y2)
cropimage = image[y1:y2, x1:x2]
# print(cropimage.shape)
crop_name = img + "_" + str(n) + '.jpg'
path = 'F:xxxx'
cv2.imwrite(os.path.join(path,crop_name),cropimage)
n = n+1