參考matlab計算輪廓內切圓
初衷是為了求裂縫的最大寬度
直接上**
import random
import cv2
import math
import numpy as np
from numpy.ma import cos, sin
import matplotlib.pyplot as plt
def max_circle(f):
img = cv2.imread(f, cv2.imread_color)
img_gray = cv2.cvtcolor(img, cv2.color_bgr2gray)
# _, img_gray = cv2.threshold(img_gray, 0, 255, cv2.thresh_binary + cv2.thresh_otsu)
"""cv2.retr_external表示只檢測外輪廓
cv2.retr_list檢測的輪廓不建立等級關係
cv2.retr_ccomp建立兩個等級的輪廓,上面的一層為外邊界,裡面的一層為內孔的邊界資訊。如果內孔內還有乙個連通物體,這個物體的邊界也在頂層。
cv2.retr_tree建立乙個等級樹結構的輪廓。
第三個引數method為輪廓的近似辦法
"""for c in contous:
left_x = min(c[:, 0, 0])
right_x = max(c[:, 0, 0])
down_y = max(c[:, 0, 1])
up_y = min(c[:, 0, 1])
upper_r = min(right_x - left_x, down_y - up_y) / 2
# 定義相切二分精度
precision = math.sqrt((right_x - left_x) ** 2 + (down_y - up_y) ** 2) / (2 ** 13)
# 構造包含輪廓的矩形的所有畫素點
nx = 2 ** 8
ny = 2 ** 8
pixel_x = np.linspace(left_x, right_x, nx)
pixel_y = np.linspace(up_y, down_y, ny)
# [pixel_x, pixel_y] = ndgrid(pixel_x, pixel_y);
# pixel_x = reshape(pixel_x, numel(pixel_x), 1);
# pixel_y = reshape(pixel_y, numel(pixel_y), 1);
xx, yy = np.meshgrid(pixel_x, pixel_y)
# % 篩選出輪廓內所有畫素點
in_list =
for c in contous:
for i in range(pixel_x.shape[0]):
for j in range(pixel_x.shape[0]):
if cv2.pointpolygontest(c, (xx[i][j], yy[i][j]), false) > 0:
in_point = np.array(in_list)
pixel_x = in_point[:, 0]
pixel_y = in_point[:, 1]
# 隨機搜尋百分之一畫素提高內切圓半徑下限
n = len(in_point)
rand_index = random.sample(range(n), n // 100)
rand_index.sort()
radius = 0
big_r = upper_r
center = none
for id in rand_index:
tr = iterated_optimal_incircle_radius_get(c, in_point[id][0], in_point[id][1], radius, big_r, precision)
if tr > radius:
radius = tr
center = (in_point[id][0], in_point[id][1]) # 只有半徑變大才允許位置變更,否則保持之前位置不變
# 迴圈搜尋剩餘畫素對應內切圓半徑
loops_index = [i for i in range(n) if i not in rand_index]
for id in loops_index:
tr = iterated_optimal_incircle_radius_get(c, in_point[id][0], in_point[id][1], radius, big_r, precision)
if tr > radius:
radius = tr
center = (in_point[id][0], in_point[id][1]) # 只有半徑變大才允許位置變更,否則保持之前位置不變
# 效果測試
plot_x = np.linspace(0, 2 * math.pi, 100)
circle_x = center[0] + radius * cos(plot_x)
circle_y = center[1] + radius * sin(plot_x)
print(radius * 2)
plt.figure()
plt.imshow(img_gray)
plt.plot(circle_x, circle_y)
plt.show()
def iterated_optimal_incircle_radius_get(contous, pixelx, pixely, small_r, big_r, precision):
radius = small_r
l = np.linspace(0, 2 * math.pi, 360) # 確定圓散點剖分數360, 720
circle_x = pixelx + radius * cos(l)
circle_y = pixely + radius * sin(l)
for i in range(len(circle_y)):
if cv2.pointpolygontest(contous, (circle_x[i], circle_y[i]), false) < 0: # 如果圓散集有在輪廓之外的點
return 0
while big_r - small_r >= precision: # 二分法尋找最大半徑
half_r = (small_r + big_r) / 2
circle_x = pixelx + half_r * cos(l)
circle_y = pixely + half_r * sin(l)
if_out = false
for i in range(len(circle_y)):
if cv2.pointpolygontest(contous, (circle_x[i], circle_y[i]), false) < 0: # 如果圓散集有在輪廓之外的點
big_r = half_r
if_out = true
if not if_out:
small_r = half_r
radius = small_r
return radius
if __name__ == '__main__':
max_circle('thresh_crack.png')
C 實現 任意多邊形的面積
求任意多邊形的面積 語法 result polygonarea vector polygon,int n 引數 polygon 多變形頂點陣列 n 多邊形頂點數目 返回值 多邊形面積 注意 支援任意多邊形,凹 凸皆可 多邊形頂點輸入時按順時針順序排列 include include using na...
任意多邊形面積
給定多邊形的頂點座標 有序 讓你來求這個多邊形的面積,你會怎麼做?我們知道,任意多邊形都可以分割為n個三角形,所以,如果以這為突破點,那麼我們第一步就是把給定的多邊形,分割為數個三角形,分別求面積,最後累加就可以了,把多邊形分割為三角形的方式多種多樣,在這裡,我們按照如下圖的方法分割 s點作為起始點...
任意多邊形的面積
給定多邊形的頂點座標 有序 讓你來求這個多邊形的面積,你會怎麼做?我們知道,任意多邊形都可以分割為n個三角形,所以,如果以這為突破點,那麼我們第一步就是把給定的多邊形,分割為數個三角形,分別求面積,最後累加就可以了,把多邊形分割為三角形的方式多種多樣,在這裡,我們按照如下圖的方法分割 s點作為起始點...