如何在python中将二进制图像的内容/对象居中? [英] How to center the content/object of a binary image in python?

查看:59
本文介绍了如何在python中将二进制图像的内容/对象居中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个代码,可以计算图形的方向.然后,根据此方向旋转图形,直到将其拉直.这一切都很好.我正在努力的是将旋转图形的中心移到整个图像的中心.因此,图形的中心点应与整个图像的中心点匹配.

I have a code that computes the orientation of a figure. Based on this orientation the figure is then rotated until it is straightened out. This all works fine. What I am struggling with, is getting the center of the rotated figure to the center of the whole image. So the center point of the figure should match the center point of the whole image.

输入图像:

代码:

import cv2
import numpy as np
import matplotlib.pyplot as plt

path = "inputImage.png"


image=cv2.imread(path)
gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
thresh=cv2.threshold(gray,0,255,cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]

contours,hierarchy = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
cnt1 = contours[0]
cnt=cv2.convexHull(contours[0])
angle = cv2.minAreaRect(cnt)[-1]
print("Actual angle is:"+str(angle))
rect = cv2.minAreaRect(cnt)

p=np.array(rect[1])

if p[0] < p[1]:
        print("Angle along the longer side:"+str(rect[-1] + 180))
        act_angle=rect[-1]+180
else:
        print("Angle along the longer side:"+str(rect[-1] + 90))
        act_angle=rect[-1]+90
#act_angle gives the angle of the minAreaRect with the vertical

if act_angle < 90:
        angle = (90 + angle)
        print("angleless than -45")

        # otherwise, just take the inverse of the angle to make
        # it positive
else:
        angle=act_angle-180
        print("grter than 90")

# rotate the image to deskew it
(h, w) = image.shape[:2]
print(h,w)
center = (w // 2, h // 2)
print(center)
M = cv2.getRotationMatrix2D(center, angle, 1.0)
rotated = cv2.warpAffine(image, M, (w, h),flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REPLICATE)

plt.imshow(rotated)
cv2.imwrite("rotated.png", rotated)

有输出:

如您所见,白色图形稍微偏左,我希望它能完美居中.有谁知道该怎么做?

As you can see the white figure is slightly placed to left, I want it to be perfectly centered. Does anyone know how this can be done?

编辑:我尝试了@joe的建议,并通过将图片的宽度和高度除以2,从图片的中心减去了质心坐标.必须添加到描述图像的数组中.但是我不知道如何将偏移量添加到数组中.该如何处理x和y坐标?

EDIT: I have tried @joe's suggestion and subtracted the centroid coordinates, from the center of the image by dividing the width and height of the picture by 2. From this I got an offset, this had to be added to the array that describes the image. But I don't know how I add the offset to the array. How would this work with the x and y coordinates?

代码:

img = cv2.imread("inputImage")
gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(gray_image,127,255,0)

height, width = gray_image.shape
print(img.shape)
wi=(width/2)
he=(height/2)
print(wi,he)
M = cv2.moments(thresh)

cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])

offsetX = (wi-cX)
offsetY = (he-cY)


print(offsetX,offsetY)
print(cX,cY)

推荐答案

一种方法是获取二进制对象的边界框坐标,然后使用Numpy切片来裁剪ROI.从这里我们计算新的偏移坐标,然后将ROI粘贴到新的空白蒙版上.

One approach is to obtain the bounding box coordinates of the binary object then crop the ROI using Numpy slicing. From here we calculate the new shifted coordinates then paste the ROI onto a new blank mask.

代码

import cv2
import numpy as np

# Load image as grayscale and obtain bounding box coordinates
image = cv2.imread('1.png', 0)
height, width = image.shape
x,y,w,h = cv2.boundingRect(image)

# Create new blank image and shift ROI to new coordinates
mask = np.zeros(image.shape, dtype=np.uint8)
ROI = image[y:y+h, x:x+w]
x = width//2 - ROI.shape[0]//2 
y = height//2 - ROI.shape[1]//2 
mask[y:y+h, x:x+w] = ROI

cv2.imshow('ROI', ROI)
cv2.imshow('mask', mask)
cv2.waitKey()

这篇关于如何在python中将二进制图像的内容/对象居中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆