I have frames of a video taken from a microscope. I need to crop them to a square inscribed to the circle but the issue is that the circle isn't whole (like in the following image). How can I do it? input image from microscope

我的 idea 是使用轮廓查找来获得圆的中心,然后找到整个坐标数组中每个点到中心的距离,以最大距离为半径,解析地找到正方形的角点,但肯定有更好的方法(而且我也没有找到角点的公式).

推荐答案

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

输入:

enter image description here

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()

结果:

enter image description here

Python相关问答推荐

如何让Flask 中的请求标签发挥作用

如何使用它?

如何调整QscrollArea以正确显示内部正在变化的Qgridlayout?

如果值发生变化,则列上的极性累积和

如何将多进程池声明为变量并将其导入到另一个Python文件

如何合并两个列表,并获得每个索引值最高的列表名称?

通过ManyToMany字段与Through在Django Admin中过滤

Pandas:填充行并删除重复项,但保留不同的值

如何将一组组合框重置回无 Select tkinter?

统计numpy. ndarray中的项目列表出现次数的最快方法

修改.pdb文件中的值并另存为新的

将数字数组添加到Pandas DataFrame的单元格依赖于初始化

我怎样才能让深度测试在OpenGL中使用Python和PyGame呢?

try 在单个WITH_COLUMNS_SEQ操作中链接表达式时,使用Polars数据帧时出现ComputeError

Python:在cmd中添加参数时的语法

如何使用Polars从AWS S3读取镶木地板文件

判断字典中是否有多个值对

以元组为索引的Numpy多维索引

在PySpark中,可以从数组中获取任意数量的元素吗?

有理由将基于Django职业的观点个人化吗?