如何裁剪部分圆内切的正方形?

Oma*_*era 3 python opencv image-processing

我有从显微镜拍摄的视频帧。我需要将它们裁剪为与圆内切的正方形,但问题是圆不是完整的(如下图所示)。我该怎么做? 输入显微镜图像

我的想法是使用轮廓查找来获取圆的中心,然后找到整个坐标数组上的每个点到中心的距离,以最大距离作为半径并分析找到正方形的角点,但必须有是一种更好的方法(而且我也没有真正找到角点的公式)。

fmw*_*w42 6

就以圆心为中心而言,这可能不够,但使用我的迭代处理,可以裁剪为圆区域内最大矩形的近似值。

输入:

在此输入图像描述

import cv2
import numpy as np

# read image
img = cv2.imread('img.jpg')
h, w = img.shape[:2]

# threshold so border is black and rest is white (invert as needed). 
# Here I needed to specify the upper threshold at 20 as your black is not pure black.

lower = (0,0,0)
upper = (20,20,20)
mask = cv2.inRange(img, lower, upper)
mask = 255 - mask

# define top and left starting coordinates and starting width and height
top = 0
left = 0
bottom = h
right = w

# compute the mean of each side of the image and its stop test
mean_top = np.mean( mask[top:top+1, left:right] )
mean_left = np.mean( mask[top:bottom, left:left+1] )
mean_bottom = np.mean( mask[bottom-1:bottom, left:right] )
mean_right = np.mean( mask[top:bottom, right-1:right] )

mean_minimum = min(mean_top, mean_left, mean_bottom, mean_right)

top_test = "stop" if (mean_top == 255) else "go"
left_test = "stop" if (mean_left == 255) else "go"
bottom_test = "stop" if (mean_bottom == 255) else "go"
right_test = "stop" if (mean_right == 255) else "go"

# iterate to compute new side coordinates if mean of given side is not 255 (all white) and it is the current darkest side
while top_test == "go" or left_test == "go" or right_test == "go" or bottom_test == "go":

    # top processing
    if top_test == "go":
        if mean_top != 255:
            if mean_top == mean_minimum:
                top += 1
                mean_top = np.mean( mask[top:top+1, left:right] )
                mean_left = np.mean( mask[top:bottom, left:left+1] )
                mean_bottom = np.mean( mask[bottom-1:bottom, left:right] )
                mean_right = np.mean( mask[top:bottom, right-1:right] )
                mean_minimum = min(mean_top, mean_left, mean_right, mean_bottom)
                #print("top",mean_top)
                continue
        else:
            top_test = "stop"   

    # left processing
    if left_test == "go":
        if mean_left != 255:
            if mean_left == mean_minimum:
                left += 1
                mean_top = np.mean( mask[top:top+1, left:right] )
                mean_left = np.mean( mask[top:bottom, left:left+1] )
                mean_bottom = np.mean( mask[bottom-1:bottom, left:right] )
                mean_right = np.mean( mask[top:bottom, right-1:right] )
                mean_minimum = min(mean_top, mean_left, mean_right, mean_bottom)
                #print("left",mean_left)
                continue
        else:
            left_test = "stop"  

    # bottom processing
    if bottom_test == "go":
        if mean_bottom != 255:
            if mean_bottom == mean_minimum:
                bottom -= 1
                mean_top = np.mean( mask[top:top+1, left:right] )
                mean_left = np.mean( mask[top:bottom, left:left+1] )
                mean_bottom = np.mean( mask[bottom-1:bottom, left:right] )
                mean_right = np.mean( mask[top:bottom, right-1:right] )
                mean_minimum = min(mean_top, mean_left, mean_right, mean_bottom)
                #print("bottom",mean_bottom)
                continue
        else:
            bottom_test = "stop"    

    # right processing
    if right_test == "go":
        if mean_right != 255:
            if mean_right == mean_minimum:
                right -= 1
                mean_top = np.mean( mask[top:top+1, left:right] )
                mean_left = np.mean( mask[top:bottom, left:left+1] )
                mean_bottom = np.mean( mask[bottom-1:bottom, left:right] )
                mean_right = np.mean( mask[top:bottom, right-1:right] )
                mean_minimum = min(mean_top, mean_left, mean_right, mean_bottom)
                #print("right",mean_right)
                continue
        else:
            right_test = "stop" 


# crop input
result = img[top:bottom, left:right]

# print crop values 
print("top: ",top)
print("bottom: ",bottom)
print("left: ",left)
print("right: ",right)
print("height:",result.shape[0])
print("width:",result.shape[1])

# save cropped image
#cv2.imwrite('border_image1_cropped.png',result)
cv2.imwrite('img_cropped.png',result)
cv2.imwrite('img_mask.png',mask)

# show the images
cv2.imshow("mask", mask)
cv2.imshow("cropped", result)
cv2.waitKey(0)
cv2.destroyAllWindows()
Run Code Online (Sandbox Code Playgroud)

结果:

在此输入图像描述