V1.0
|
|
@ -0,0 +1,3 @@
|
||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="PYTHON_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
|
|
@ -0,0 +1,112 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="PublishConfigData" remoteFilesAllowedToDisappearOnAutoupload="false">
|
||||||
|
<serverData>
|
||||||
|
<paths name="root@212.129.223.66:6023 password">
|
||||||
|
<serverdata>
|
||||||
|
<mappings>
|
||||||
|
<mapping local="$PROJECT_DIR$" web="/" />
|
||||||
|
</mappings>
|
||||||
|
</serverdata>
|
||||||
|
</paths>
|
||||||
|
<paths name="thsw@192.168.10.11:22 password">
|
||||||
|
<serverdata>
|
||||||
|
<mappings>
|
||||||
|
<mapping local="$PROJECT_DIR$" web="/" />
|
||||||
|
</mappings>
|
||||||
|
</serverdata>
|
||||||
|
</paths>
|
||||||
|
<paths name="thsw@192.168.10.11:22 password (2)">
|
||||||
|
<serverdata>
|
||||||
|
<mappings>
|
||||||
|
<mapping local="$PROJECT_DIR$" web="/" />
|
||||||
|
</mappings>
|
||||||
|
</serverdata>
|
||||||
|
</paths>
|
||||||
|
<paths name="thsw@192.168.10.11:22 password (3)">
|
||||||
|
<serverdata>
|
||||||
|
<mappings>
|
||||||
|
<mapping local="$PROJECT_DIR$" web="/" />
|
||||||
|
</mappings>
|
||||||
|
</serverdata>
|
||||||
|
</paths>
|
||||||
|
<paths name="thsw@192.168.10.11:22 password (4)">
|
||||||
|
<serverdata>
|
||||||
|
<mappings>
|
||||||
|
<mapping local="$PROJECT_DIR$" web="/" />
|
||||||
|
</mappings>
|
||||||
|
</serverdata>
|
||||||
|
</paths>
|
||||||
|
<paths name="thsw@192.168.10.11:22 password (5)">
|
||||||
|
<serverdata>
|
||||||
|
<mappings>
|
||||||
|
<mapping local="$PROJECT_DIR$" web="/" />
|
||||||
|
</mappings>
|
||||||
|
</serverdata>
|
||||||
|
</paths>
|
||||||
|
<paths name="thsw@192.168.10.11:22 password (6)">
|
||||||
|
<serverdata>
|
||||||
|
<mappings>
|
||||||
|
<mapping local="$PROJECT_DIR$" web="/" />
|
||||||
|
</mappings>
|
||||||
|
</serverdata>
|
||||||
|
</paths>
|
||||||
|
<paths name="thsw@192.168.10.11:22 password (7)">
|
||||||
|
<serverdata>
|
||||||
|
<mappings>
|
||||||
|
<mapping local="$PROJECT_DIR$" web="/" />
|
||||||
|
</mappings>
|
||||||
|
</serverdata>
|
||||||
|
</paths>
|
||||||
|
<paths name="thsw@221.226.114.142:1011 password">
|
||||||
|
<serverdata>
|
||||||
|
<mappings>
|
||||||
|
<mapping local="$PROJECT_DIR$" web="/" />
|
||||||
|
</mappings>
|
||||||
|
</serverdata>
|
||||||
|
</paths>
|
||||||
|
<paths name="thsw@221.226.114.142:1011 password (2)">
|
||||||
|
<serverdata>
|
||||||
|
<mappings>
|
||||||
|
<mapping local="$PROJECT_DIR$" web="/" />
|
||||||
|
</mappings>
|
||||||
|
</serverdata>
|
||||||
|
</paths>
|
||||||
|
<paths name="thsw@221.226.114.142:1011 password (3)">
|
||||||
|
<serverdata>
|
||||||
|
<mappings>
|
||||||
|
<mapping local="$PROJECT_DIR$" web="/" />
|
||||||
|
</mappings>
|
||||||
|
</serverdata>
|
||||||
|
</paths>
|
||||||
|
<paths name="thsw@221.226.114.142:1011 password (4)">
|
||||||
|
<serverdata>
|
||||||
|
<mappings>
|
||||||
|
<mapping local="$PROJECT_DIR$" web="/" />
|
||||||
|
</mappings>
|
||||||
|
</serverdata>
|
||||||
|
</paths>
|
||||||
|
<paths name="thsw@221.226.114.142:1011 password (5)">
|
||||||
|
<serverdata>
|
||||||
|
<mappings>
|
||||||
|
<mapping local="$PROJECT_DIR$" web="/" />
|
||||||
|
</mappings>
|
||||||
|
</serverdata>
|
||||||
|
</paths>
|
||||||
|
<paths name="thsw@221.226.114.142:1011 password (6)">
|
||||||
|
<serverdata>
|
||||||
|
<mappings>
|
||||||
|
<mapping local="$PROJECT_DIR$" web="/" />
|
||||||
|
</mappings>
|
||||||
|
</serverdata>
|
||||||
|
</paths>
|
||||||
|
<paths name="thsw@221.226.114.142:1011 password (7)">
|
||||||
|
<serverdata>
|
||||||
|
<mappings>
|
||||||
|
<mapping local="$PROJECT_DIR$" web="/" />
|
||||||
|
</mappings>
|
||||||
|
</serverdata>
|
||||||
|
</paths>
|
||||||
|
</serverData>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<option name="ignoredPackages">
|
||||||
|
<value>
|
||||||
|
<list size="68">
|
||||||
|
<item index="0" class="java.lang.String" itemvalue="thop" />
|
||||||
|
<item index="1" class="java.lang.String" itemvalue="Cython" />
|
||||||
|
<item index="2" class="java.lang.String" itemvalue="pycocotools" />
|
||||||
|
<item index="3" class="java.lang.String" itemvalue="pandas" />
|
||||||
|
<item index="4" class="java.lang.String" itemvalue="tqdm" />
|
||||||
|
<item index="5" class="java.lang.String" itemvalue="scipy" />
|
||||||
|
<item index="6" class="java.lang.String" itemvalue="pillow" />
|
||||||
|
<item index="7" class="java.lang.String" itemvalue="numpy" />
|
||||||
|
<item index="8" class="java.lang.String" itemvalue="requests" />
|
||||||
|
<item index="9" class="java.lang.String" itemvalue="easydict" />
|
||||||
|
<item index="10" class="java.lang.String" itemvalue="imutil" />
|
||||||
|
<item index="11" class="java.lang.String" itemvalue="pkg-resources" />
|
||||||
|
<item index="12" class="java.lang.String" itemvalue="hyperpyyaml" />
|
||||||
|
<item index="13" class="java.lang.String" itemvalue="pytest" />
|
||||||
|
<item index="14" class="java.lang.String" itemvalue="yamllint" />
|
||||||
|
<item index="15" class="java.lang.String" itemvalue="sentencepiece" />
|
||||||
|
<item index="16" class="java.lang.String" itemvalue="black" />
|
||||||
|
<item index="17" class="java.lang.String" itemvalue="pre-commit" />
|
||||||
|
<item index="18" class="java.lang.String" itemvalue="pycodestyle" />
|
||||||
|
<item index="19" class="java.lang.String" itemvalue="torch" />
|
||||||
|
<item index="20" class="java.lang.String" itemvalue="torchaudio" />
|
||||||
|
<item index="21" class="java.lang.String" itemvalue="flake8" />
|
||||||
|
<item index="22" class="java.lang.String" itemvalue="huggingface_hub" />
|
||||||
|
<item index="23" class="java.lang.String" itemvalue="numba" />
|
||||||
|
<item index="24" class="java.lang.String" itemvalue="librosa" />
|
||||||
|
<item index="25" class="java.lang.String" itemvalue="visualdl" />
|
||||||
|
<item index="26" class="java.lang.String" itemvalue="pyaudio" />
|
||||||
|
<item index="27" class="java.lang.String" itemvalue="joblib" />
|
||||||
|
<item index="28" class="java.lang.String" itemvalue="packaging" />
|
||||||
|
<item index="29" class="java.lang.String" itemvalue="opencv-python" />
|
||||||
|
<item index="30" class="java.lang.String" itemvalue="pytorch-lightning" />
|
||||||
|
<item index="31" class="java.lang.String" itemvalue="scikit-learn" />
|
||||||
|
<item index="32" class="java.lang.String" itemvalue="speechbrain" />
|
||||||
|
<item index="33" class="java.lang.String" itemvalue="webrtcvad" />
|
||||||
|
<item index="34" class="java.lang.String" itemvalue="yacs" />
|
||||||
|
<item index="35" class="java.lang.String" itemvalue="prefetch_generator" />
|
||||||
|
<item index="36" class="java.lang.String" itemvalue="pathspec" />
|
||||||
|
<item index="37" class="java.lang.String" itemvalue="addict" />
|
||||||
|
<item index="38" class="java.lang.String" itemvalue="loguru" />
|
||||||
|
<item index="39" class="java.lang.String" itemvalue="glog" />
|
||||||
|
<item index="40" class="java.lang.String" itemvalue="mmcv" />
|
||||||
|
<item index="41" class="java.lang.String" itemvalue="Shapely" />
|
||||||
|
<item index="42" class="java.lang.String" itemvalue="yapf" />
|
||||||
|
<item index="43" class="java.lang.String" itemvalue="cityscapesscripts" />
|
||||||
|
<item index="44" class="java.lang.String" itemvalue="asynctest" />
|
||||||
|
<item index="45" class="java.lang.String" itemvalue="albumentations" />
|
||||||
|
<item index="46" class="java.lang.String" itemvalue="imagecorruptions" />
|
||||||
|
<item index="47" class="java.lang.String" itemvalue="pytest-runner" />
|
||||||
|
<item index="48" class="java.lang.String" itemvalue="pytest-cov" />
|
||||||
|
<item index="49" class="java.lang.String" itemvalue="isort" />
|
||||||
|
<item index="50" class="java.lang.String" itemvalue="kwarray" />
|
||||||
|
<item index="51" class="java.lang.String" itemvalue="xdoctest" />
|
||||||
|
<item index="52" class="java.lang.String" itemvalue="codecov" />
|
||||||
|
<item index="53" class="java.lang.String" itemvalue="ubelt" />
|
||||||
|
<item index="54" class="java.lang.String" itemvalue="Pillow" />
|
||||||
|
<item index="55" class="java.lang.String" itemvalue="terminaltables" />
|
||||||
|
<item index="56" class="java.lang.String" itemvalue="tensorflow" />
|
||||||
|
<item index="57" class="java.lang.String" itemvalue="tensorflow_gpu" />
|
||||||
|
<item index="58" class="java.lang.String" itemvalue="scikit_learn" />
|
||||||
|
<item index="59" class="java.lang.String" itemvalue="matplotlib" />
|
||||||
|
<item index="60" class="java.lang.String" itemvalue="opencv_contrib_python" />
|
||||||
|
<item index="61" class="java.lang.String" itemvalue="tensorboard" />
|
||||||
|
<item index="62" class="java.lang.String" itemvalue="seaborn" />
|
||||||
|
<item index="63" class="java.lang.String" itemvalue="h5py" />
|
||||||
|
<item index="64" class="java.lang.String" itemvalue="torchvision" />
|
||||||
|
<item index="65" class="java.lang.String" itemvalue="opencv_python" />
|
||||||
|
<item index="66" class="java.lang.String" itemvalue="pytorch" />
|
||||||
|
<item index="67" class="java.lang.String" itemvalue="opencv" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
</inspection_tool>
|
||||||
|
</profile>
|
||||||
|
</component>
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<settings>
|
||||||
|
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||||
|
<version value="1.0" />
|
||||||
|
</settings>
|
||||||
|
</component>
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7 (project)" project-jdk-type="Python SDK" />
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/7_Widen_boundary.iml" filepath="$PROJECT_DIR$/.idea/7_Widen_boundary.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
# -*- coding: UTF-8 -*-
|
||||||
|
import cv2
|
||||||
|
import numpy as np
|
||||||
|
import skimage.exposure
|
||||||
|
'''
|
||||||
|
两个区域间最短距离
|
||||||
|
https://www.cnpython.com/qa/1329750
|
||||||
|
'''
|
||||||
|
# read image
|
||||||
|
img = cv2.imread('demo/73.png')
|
||||||
|
h, w = img.shape[:2]
|
||||||
|
|
||||||
|
# convert to gray
|
||||||
|
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
||||||
|
|
||||||
|
# threshold to binary
|
||||||
|
thresh = cv2.threshold(gray, 128, 255, cv2.THRESH_BINARY)[1]
|
||||||
|
|
||||||
|
# create zeros mask 2 pixels larger in each dimension
|
||||||
|
mask = np.zeros([h + 2, w + 2], np.uint8)
|
||||||
|
|
||||||
|
# floodfill white between two polygons at 240,240
|
||||||
|
ffimg = thresh.copy()
|
||||||
|
ffimg = cv2.floodFill(ffimg, mask, (240,240), 255)[1]
|
||||||
|
|
||||||
|
# apply distance transform
|
||||||
|
distimg = ffimg.copy()
|
||||||
|
distimg = cv2.distanceTransform(distimg, cv2.DIST_L2, 5)
|
||||||
|
|
||||||
|
# Maximum spacing between polygons is 2 * largest value in distimg
|
||||||
|
max = 2*np.amax(distimg)
|
||||||
|
print('maximum spacing:', max)
|
||||||
|
|
||||||
|
print('')
|
||||||
|
|
||||||
|
# convert to polar image using (any) point in the center 'hole' of distimg
|
||||||
|
polar = cv2.warpPolar(distimg, (360,360), (320,330), 250, cv2.INTER_CUBIC+cv2.WARP_POLAR_LINEAR)
|
||||||
|
|
||||||
|
# get maximum value along each row
|
||||||
|
polar_max = np.amax(polar, axis=1)
|
||||||
|
|
||||||
|
# find max and min values from row maximum values
|
||||||
|
max = 2*np.amax(polar_max)
|
||||||
|
min = 2*np.amin(polar_max)
|
||||||
|
print('maximum spacing:', max)
|
||||||
|
print('minimum spacing:', min)
|
||||||
|
|
||||||
|
# scale distance image for viewing
|
||||||
|
distimg = skimage.exposure.rescale_intensity(distimg, in_range='image', out_range=(0,255))
|
||||||
|
distimg = distimg.astype(np.uint8)
|
||||||
|
|
||||||
|
# scale polar image for viewing
|
||||||
|
polar = skimage.exposure.rescale_intensity(polar, in_range='image', out_range=(0,255))
|
||||||
|
polar = polar.astype(np.uint8)
|
||||||
|
|
||||||
|
# save image
|
||||||
|
cv2.imwrite('polygons_floodfill.png',ffimg)
|
||||||
|
cv2.imwrite('polygons_distance.png',distimg)
|
||||||
|
cv2.imwrite('polygons_distance_polar.png',polar)
|
||||||
|
|
||||||
|
# show the images
|
||||||
|
cv2.imshow("thresh", thresh)
|
||||||
|
cv2.imshow("floodfill", ffimg)
|
||||||
|
cv2.imshow("distance", distimg)
|
||||||
|
cv2.imshow("polar", polar)
|
||||||
|
cv2.waitKey(0)
|
||||||
|
cv2.destroyAllWindows()
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
import cv2
|
||||||
|
import numpy as np
|
||||||
|
'''
|
||||||
|
两个区域间最短距离
|
||||||
|
https://www.lmlphp.com/user/154997/article/item/3778387/
|
||||||
|
'''
|
||||||
|
|
||||||
|
def contours(layer):
|
||||||
|
gray = cv2.cvtColor(layer, cv2.COLOR_BGR2GRAY)
|
||||||
|
ret,binary = cv2.threshold(gray, 1,255,cv2.THRESH_BINARY)
|
||||||
|
contours, hierarchy = cv2.findContours(binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
|
||||||
|
#drawn = cv2.drawContours(image,contours,-1,(150,150,150),3)
|
||||||
|
return contours #, drawn
|
||||||
|
|
||||||
|
def minDistance(contour, contourOther):
|
||||||
|
distanceMin = 99999999
|
||||||
|
for xA, yA in contour[0]:
|
||||||
|
for xB, yB in contourOther[0]:
|
||||||
|
distance = ((xB-xA)**2+(yB-yA)**2)**(1/2) # distance formula
|
||||||
|
if (distance < distanceMin):
|
||||||
|
distanceMin = distance
|
||||||
|
return distanceMin
|
||||||
|
|
||||||
|
def cntDistanceCompare(contoursA, contoursB):
|
||||||
|
cumMinDistList = []
|
||||||
|
for contourA in contoursA:
|
||||||
|
indMinDistList = []
|
||||||
|
for contourB in contoursB:
|
||||||
|
minDist = minDistance(contourA,contourB)
|
||||||
|
indMinDistList.append(minDist)
|
||||||
|
cumMinDistList.append(indMinDistList)
|
||||||
|
l = cumMinDistList
|
||||||
|
return sum(l)/len(l) #returns mean distance
|
||||||
|
|
||||||
|
def maskBuilder(bgr,hl,hh,sl,sh,vl,vh):
|
||||||
|
hsv = cv2.cvtColor(bgr, cv2.COLOR_BGR2HSV)
|
||||||
|
lower_bound = np.array([hl,sl,vl],dtype=np.uint8)
|
||||||
|
upper_bound = np.array([hh,sh,vh],dtype=np.uint8)
|
||||||
|
return cv2.inRange(hsv, lower_bound,upper_bound)
|
||||||
|
|
||||||
|
def getContourCenters(contourData):
|
||||||
|
contourCoordinates = []
|
||||||
|
for contour in contourData:
|
||||||
|
moments = cv2.moments(contour)
|
||||||
|
contourX = int(moments['m10'] / float(moments['m00']))
|
||||||
|
contourY = int(moments['m01'] / float(moments['m00']))
|
||||||
|
contourCoordinates += [[contourX, contourY]]
|
||||||
|
return contourCoordinates
|
||||||
|
|
||||||
|
img = cv2.imread('demo/73.png')
|
||||||
|
maskA=maskBuilder(img, 150,185, 40,220, 65,240)
|
||||||
|
maskB=maskBuilder(img, 3,20, 50,180, 20,250)
|
||||||
|
layerA = cv2.bitwise_and(img, img, mask = maskA)
|
||||||
|
layerB = cv2.bitwise_and(img, img, mask = maskB)
|
||||||
|
contoursA = contours(layerA)
|
||||||
|
contoursB = contours(layerB)
|
||||||
|
|
||||||
|
print(getContourCenters(contoursA))
|
||||||
|
print(getContourCenters(contoursB))
|
||||||
|
|
||||||
|
#print cntDistanceCompare(contoursA, contoursB)
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
import cv2
|
||||||
|
import numpy as np
|
||||||
|
'''
|
||||||
|
两个区域间最短距离
|
||||||
|
https://blog.csdn.net/weixin_42515093/article/details/112713403
|
||||||
|
'''
|
||||||
|
# 1、在二值图像中获取轮廓
|
||||||
|
import cv2
|
||||||
|
img = cv2.imread('demo/73.png')
|
||||||
|
imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
||||||
|
ret, thresh = cv2.threshold(imgray, 127, 255, 0)
|
||||||
|
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
|
||||||
|
|
||||||
|
# 2、绘制轮廓
|
||||||
|
# To draw all the contours in an image:
|
||||||
|
cv2.drawContours(img, contours, -1, (0,255,0), 3)
|
||||||
|
# To draw an individual contour, say 4th contour:
|
||||||
|
cv2.drawContours(img, contours, 3, (0,255,0), 3)
|
||||||
|
# But most of the time, below method will be useful:
|
||||||
|
cnt = contours[4]
|
||||||
|
cv2.drawContours(img, [cnt], 0, (0,255,0), 3)
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
# -*- coding: UTF-8 -*-
|
||||||
|
import cv2
|
||||||
|
import time
|
||||||
|
import numpy as np
|
||||||
|
import skimage.exposure
|
||||||
|
'''
|
||||||
|
两个区域间最短距离
|
||||||
|
https://www.cnpython.com/qa/1329750
|
||||||
|
'''
|
||||||
|
|
||||||
|
import math
|
||||||
|
|
||||||
|
|
||||||
|
def downsample(num_arr,downsample_rate):
|
||||||
|
'''
|
||||||
|
下采样数组,隔着downsample_rate个数取一个值
|
||||||
|
num_arr为数组
|
||||||
|
downsample_rate为采用概率,为1-n的正整数
|
||||||
|
'''
|
||||||
|
num_arr_temp=[]
|
||||||
|
for i in range(len(num_arr)//downsample_rate-1):
|
||||||
|
num_arr_temp.append(num_arr[i*downsample_rate])
|
||||||
|
return num_arr_temp
|
||||||
|
|
||||||
|
# 中间输入的代码
|
||||||
|
# 将数组存在num_arr1和num_arr2中
|
||||||
|
|
||||||
|
t1=time.time()
|
||||||
|
# 1.读入图片
|
||||||
|
# img = cv2.imread('demo/171.png')
|
||||||
|
img = cv2.imread('demo/9.png')
|
||||||
|
t2=time.time()
|
||||||
|
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
||||||
|
|
||||||
|
contours, thresh = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
|
||||||
|
|
||||||
|
# 2.寻找轮廓(多边界)
|
||||||
|
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_LIST, 2)
|
||||||
|
|
||||||
|
|
||||||
|
# 3.轮廓数组转为列表(多边界)
|
||||||
|
list_contours=[]
|
||||||
|
record=[]
|
||||||
|
num_arr1=contours[0]
|
||||||
|
num_arr2=contours[1]
|
||||||
|
|
||||||
|
|
||||||
|
# 3.对边界进行下采样,减小点数量。
|
||||||
|
num_arr11=downsample(num_arr1,10) #下采样边界点
|
||||||
|
num_arr22=downsample(num_arr2,10) #下采样边界点
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
print(num_arr1)
|
||||||
|
t3=time.time()
|
||||||
|
for i in num_arr11:
|
||||||
|
for j in num_arr22:
|
||||||
|
# record.append(abs(i[0] - j[0]))
|
||||||
|
record.append(math.sqrt((i[0][0] - j[0][0]) ** 2 +(i[0][1] - j[0][1]) ** 2 ) )
|
||||||
|
|
||||||
|
print('两区域最小距离',min(record))
|
||||||
|
t4=time.time()
|
||||||
|
|
||||||
|
print('读图时间:%s 找边界时间:%s 区域最短距离计算时间:%s'%(t2-t1,t3-t2,t4-t3))
|
||||||
|
|
||||||
|
|
@ -0,0 +1,98 @@
|
||||||
|
# -*- coding: UTF-8 -*-
|
||||||
|
import cv2
|
||||||
|
import time
|
||||||
|
import numpy as np
|
||||||
|
import skimage.exposure
|
||||||
|
'''
|
||||||
|
两个区域间最短距离
|
||||||
|
https://www.cnpython.com/qa/1329750
|
||||||
|
'''
|
||||||
|
|
||||||
|
import math
|
||||||
|
|
||||||
|
|
||||||
|
def downsample(num_arr,downsample_rate):
|
||||||
|
'''
|
||||||
|
下采样数组,隔着downsample_rate个数取一个值
|
||||||
|
num_arr为数组
|
||||||
|
downsample_rate为采用概率,为1-n的正整数
|
||||||
|
'''
|
||||||
|
num_arr_temp=[]
|
||||||
|
for i in range(len(num_arr)//downsample_rate-1):
|
||||||
|
num_arr_temp.append(num_arr[i*downsample_rate])
|
||||||
|
return num_arr_temp
|
||||||
|
|
||||||
|
|
||||||
|
def array_distance(arr1,arr2):
|
||||||
|
'''
|
||||||
|
计算两个数组中,每任意两个点之间L2距离
|
||||||
|
arr1和arr2都必须是numpy数组
|
||||||
|
且维度分别是mx2,nx2
|
||||||
|
输出数组维度为mxn
|
||||||
|
'''
|
||||||
|
m,_=arr1.shape
|
||||||
|
n,_=arr2.shape
|
||||||
|
arr1_power = np.power(arr1, 2)
|
||||||
|
xxx=arr1_power[:, 0]
|
||||||
|
arr1_power_sum = arr1_power[:, 0] + arr1_power[:, 1] #第1区域,x与y的平方和
|
||||||
|
yyy=arr1_power_sum
|
||||||
|
arr1_power_sum = np.tile(arr1_power_sum, (n, 1)) #将arr1_power_sum沿着y轴复制n倍,沿着x轴复制1倍,这里用于与arr2进行计算。 nxm 维度
|
||||||
|
zzz=arr1_power_sum
|
||||||
|
arr1_power_sum = arr1_power_sum.T #将arr1_power_sum进行转置
|
||||||
|
arr2_power = np.power(arr2, 2)
|
||||||
|
arr2_power_sum = arr2_power[:, 0] + arr2_power[:, 1] #第2区域,x与y的平方和
|
||||||
|
arr2_power_sum = np.tile(arr2_power_sum, (m, 1)) #将arr1_power_sum沿着y轴复制m倍,沿着x轴复制1倍,这里用于与arr1进行计算。 mxn 维度
|
||||||
|
dis = arr1_power_sum + arr2_power_sum - (2 * np.dot(arr1, arr2.T)) #np.dot(arr1, arr2.T)矩阵相乘,得到xy的值。
|
||||||
|
dis = np.sqrt(dis)
|
||||||
|
return dis
|
||||||
|
|
||||||
|
# 中间输入的代码
|
||||||
|
# 将数组存在num_arr1和num_arr2中
|
||||||
|
|
||||||
|
t1=time.time()
|
||||||
|
# 1.读入图片
|
||||||
|
# img = cv2.imread('demo/171.png')
|
||||||
|
img = cv2.imread('demo/9.png')
|
||||||
|
t2=time.time()
|
||||||
|
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
||||||
|
|
||||||
|
contours, thresh = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
|
||||||
|
|
||||||
|
# 2.寻找轮廓(多边界)
|
||||||
|
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_LIST, 2)
|
||||||
|
|
||||||
|
|
||||||
|
# 3.轮廓数组转为列表(多边界)
|
||||||
|
list_contours=[]
|
||||||
|
record=[]
|
||||||
|
num_arr1=contours[0]
|
||||||
|
num_arr2=contours[1]
|
||||||
|
|
||||||
|
|
||||||
|
ssss1=np.squeeze(num_arr1, 1)
|
||||||
|
ssss2=np.squeeze(num_arr2, 1)
|
||||||
|
|
||||||
|
|
||||||
|
# 3.对边界进行下采样,减小点数量。
|
||||||
|
num_arr11=downsample(num_arr1,10) #下采样边界点
|
||||||
|
num_arr22=downsample(num_arr2,10) #下采样边界点
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
print(num_arr1)
|
||||||
|
t3=time.time()
|
||||||
|
|
||||||
|
dist_arr=array_distance(ssss1,ssss2)
|
||||||
|
min_dist=dist_arr[dist_arr>0].min()
|
||||||
|
|
||||||
|
print(min_dist)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# print('两区域最小距离',min(record))
|
||||||
|
t4=time.time()
|
||||||
|
|
||||||
|
print('读图时间:%s 找边界时间:%s 区域最短距离计算时间:%s'%(t2-t1,t3-t2,t4-t3))
|
||||||
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
1、0_mindist_between_two_array_2.py
|
||||||
|
两个区域之间最小距离(采用数组计算)
|
||||||
|
|
||||||
|
0_mindist_between_two_array.py
|
||||||
|
两个区域之间最小距离(for循环计算,耗时严重)
|
||||||
|
|
||||||
|
2、main_jicheng_multiple_area.py
|
||||||
|
将区域往外扩充一定数量的像素点。
|
||||||
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 73 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 8.0 KiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 1.0 MiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 1.0 MiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 994 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 959 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 990 KiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 1018 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 1.0 MiB |
|
After Width: | Height: | Size: 1.0 MiB |
|
After Width: | Height: | Size: 9.6 KiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 1004 KiB |
|
After Width: | Height: | Size: 941 KiB |
|
After Width: | Height: | Size: 950 KiB |
|
After Width: | Height: | Size: 1.0 MiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 1.0 MiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 253 KiB |
|
|
@ -0,0 +1,23 @@
|
||||||
|
# -*- coding: UTF-8 -*-
|
||||||
|
import cv2 as cv
|
||||||
|
import numpy
|
||||||
|
# 1.读入图片
|
||||||
|
img = cv.imread('demo/171.png')
|
||||||
|
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
|
||||||
|
contours, thresh = cv.threshold(img_gray, 0, 255, cv.THRESH_BINARY + cv.THRESH_OTSU)
|
||||||
|
|
||||||
|
# 2.寻找轮廓
|
||||||
|
contours, hierarchy = cv.findContours(thresh, cv.RETR_LIST, 2)
|
||||||
|
|
||||||
|
print(len(contours),hierarchy)
|
||||||
|
|
||||||
|
# 3.绘制轮廓
|
||||||
|
cv.drawContours(img, contours, -1, (0, 0, 255), 2)
|
||||||
|
|
||||||
|
# cv.imshow('result',img)
|
||||||
|
# cv.resizeWindow('result', 640, 480);
|
||||||
|
cv.namedWindow("boundary",0);
|
||||||
|
cv.resizeWindow("boundary", 640, 480);
|
||||||
|
cv.imshow("boundary",img)
|
||||||
|
cv.waitKey(0)
|
||||||
|
cv.destroyAllWindows()
|
||||||
|
|
@ -0,0 +1,184 @@
|
||||||
|
# -*- coding: UTF-8 -*-
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- encoding: utf-8 -*-
|
||||||
|
'''
|
||||||
|
@File : 多边形等距缩放.py
|
||||||
|
@data :2021/7/5 15:53
|
||||||
|
@Desciption :
|
||||||
|
@Version :
|
||||||
|
@License :
|
||||||
|
'''
|
||||||
|
|
||||||
|
import cv2
|
||||||
|
import numpy as np
|
||||||
|
def scale(data, sec_dis):
|
||||||
|
"""多边形等距缩放
|
||||||
|
Args:
|
||||||
|
data: 多边形按照逆时针顺序排列的的点集
|
||||||
|
sec_dis: 缩放距离
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
缩放后的多边形点集
|
||||||
|
"""
|
||||||
|
num = len(data)
|
||||||
|
scal_data = []
|
||||||
|
for i in range(num):
|
||||||
|
x1 = data[(i) % num][0] - data[(i - 1) % num][0]
|
||||||
|
y1 = data[(i) % num][1] - data[(i - 1) % num][1]
|
||||||
|
x2 = data[(i + 1) % num][0] - data[(i) % num][0]
|
||||||
|
y2 = data[(i + 1) % num][1] - data[(i) % num][1]
|
||||||
|
|
||||||
|
d_A = (x1 ** 2 + y1 ** 2) ** 0.5
|
||||||
|
d_B = (x2 ** 2 + y2 ** 2) ** 0.5
|
||||||
|
|
||||||
|
Vec_Cross = (x1 * y2) - (x2 * y1)
|
||||||
|
if (d_A * d_B==0):
|
||||||
|
continue
|
||||||
|
sin_theta = Vec_Cross / (d_A * d_B)
|
||||||
|
if (sin_theta==0):
|
||||||
|
continue
|
||||||
|
dv = sec_dis / sin_theta
|
||||||
|
|
||||||
|
v1_x = (dv / d_A) * x1
|
||||||
|
v1_y = (dv / d_A) * y1
|
||||||
|
|
||||||
|
v2_x = (dv / d_B) * x2
|
||||||
|
v2_y = (dv / d_B) * y2
|
||||||
|
|
||||||
|
PQ_x = v1_x - v2_x
|
||||||
|
PQ_y = v1_y - v2_y
|
||||||
|
|
||||||
|
Q_x = data[(i) % num][0] + PQ_x
|
||||||
|
Q_y = data[(i) % num][1] + PQ_y
|
||||||
|
scal_data.append([Q_x, Q_y])
|
||||||
|
return scal_data
|
||||||
|
|
||||||
|
|
||||||
|
data = [[454 , 76],
|
||||||
|
[448 ,78],
|
||||||
|
[444, 81],
|
||||||
|
[440 , 85],
|
||||||
|
[438, 90],
|
||||||
|
[437, 96],
|
||||||
|
[436 ,101],
|
||||||
|
[434, 107],
|
||||||
|
[432 ,112],
|
||||||
|
[431 ,117],
|
||||||
|
[430 ,123],
|
||||||
|
[429, 129],
|
||||||
|
[428, 134],
|
||||||
|
[427, 140],
|
||||||
|
[427, 145],
|
||||||
|
[427, 151],
|
||||||
|
[427 ,157],
|
||||||
|
[427 ,163],
|
||||||
|
[427, 169],
|
||||||
|
[427, 175],
|
||||||
|
[427, 181],
|
||||||
|
[427, 187],
|
||||||
|
[428, 193],
|
||||||
|
[428 ,199],
|
||||||
|
[429, 204],
|
||||||
|
[429, 210],
|
||||||
|
[429 ,216],
|
||||||
|
[430, 222],
|
||||||
|
[431, 227],
|
||||||
|
[431, 233],
|
||||||
|
[431, 239],
|
||||||
|
[432, 245],
|
||||||
|
[433, 250],
|
||||||
|
[434, 256],
|
||||||
|
[435 ,261],
|
||||||
|
[436 ,267],
|
||||||
|
[437 ,272],
|
||||||
|
[438, 278],
|
||||||
|
[439, 283],
|
||||||
|
[441, 289],
|
||||||
|
[442, 294],
|
||||||
|
[443, 300],
|
||||||
|
[445, 305],
|
||||||
|
[446, 310],
|
||||||
|
[448, 316],
|
||||||
|
[450, 321],
|
||||||
|
[453, 330],
|
||||||
|
[461, 334],
|
||||||
|
[466, 336],
|
||||||
|
[471, 338],
|
||||||
|
[477 ,340],
|
||||||
|
[482, 340],
|
||||||
|
[488, 341],
|
||||||
|
[494, 341],
|
||||||
|
[500, 341],
|
||||||
|
[506 ,341],
|
||||||
|
[511 ,340],
|
||||||
|
[517, 339],
|
||||||
|
[523 ,338],
|
||||||
|
[528, 337],
|
||||||
|
[533, 335],
|
||||||
|
[539, 333],
|
||||||
|
[544, 331],
|
||||||
|
[549, 329],
|
||||||
|
[553, 326],
|
||||||
|
[558, 322],
|
||||||
|
[562, 318],
|
||||||
|
[566, 313],
|
||||||
|
[568, 308],
|
||||||
|
[569, 303],
|
||||||
|
[570, 297],
|
||||||
|
[570, 291],
|
||||||
|
[569, 285],
|
||||||
|
[569, 280],
|
||||||
|
[568, 274],
|
||||||
|
[567, 268],
|
||||||
|
[566 ,263],
|
||||||
|
[566 ,257],
|
||||||
|
[564 ,252],
|
||||||
|
[564 ,246],
|
||||||
|
[562, 241],
|
||||||
|
[561, 235],
|
||||||
|
[560, 230],
|
||||||
|
[560, 224],
|
||||||
|
[558 ,219],
|
||||||
|
[558, 213],
|
||||||
|
[556, 207],
|
||||||
|
[555, 202],
|
||||||
|
[554, 196],
|
||||||
|
[553, 191],
|
||||||
|
[552, 185],
|
||||||
|
[550, 180],
|
||||||
|
[549, 174],
|
||||||
|
[548, 169],
|
||||||
|
[547 ,164],
|
||||||
|
[545 ,158],
|
||||||
|
[543 ,153],
|
||||||
|
[541 ,148],
|
||||||
|
[539 ,143],
|
||||||
|
[536 ,138],
|
||||||
|
[533 ,133],
|
||||||
|
[530, 128],
|
||||||
|
[528 ,124],
|
||||||
|
[524 ,119],
|
||||||
|
[520 ,115],
|
||||||
|
[515, 111],
|
||||||
|
[511, 108],
|
||||||
|
[506 ,106],
|
||||||
|
[501 ,104],
|
||||||
|
[495 ,102],
|
||||||
|
[490, 101],
|
||||||
|
[485 , 99],
|
||||||
|
[480 , 97],
|
||||||
|
[475 , 93],
|
||||||
|
[471 , 89],
|
||||||
|
[468 , 84],
|
||||||
|
[465, 80],
|
||||||
|
[460 , 76]]
|
||||||
|
|
||||||
|
data1 = scale(data,-100)
|
||||||
|
print(data1)
|
||||||
|
temp = np.ones((1300,1000,3), np.uint8) * 255
|
||||||
|
#cv2.polylines(temp, data1, 1, 255)
|
||||||
|
cv2.polylines(temp , [np.array(data , dtype=np.int32)], True, (255, 0, 0), 1)
|
||||||
|
cv2.polylines(temp , [np.array(data1 , dtype=np.int32)], True, (0, 0, 255), 1)
|
||||||
|
cv2.imshow ("img",temp)
|
||||||
|
cv2.imwrite("1.jpg",temp)
|
||||||
|
cv2.waitKey(0)
|
||||||
|
|
@ -0,0 +1,107 @@
|
||||||
|
# -*- coding: UTF-8 -*-
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- encoding: utf-8 -*-
|
||||||
|
'''
|
||||||
|
@File : 多边形等距缩放.py
|
||||||
|
@data :2021/7/5 15:53
|
||||||
|
@Desciption :
|
||||||
|
@Version :
|
||||||
|
@License :
|
||||||
|
'''
|
||||||
|
|
||||||
|
import cv2
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
def contours_2_list(data):
|
||||||
|
"""将opencv读取的边界numpy数组(3个维度)转化为list(2个维度)
|
||||||
|
Args:
|
||||||
|
data为数组
|
||||||
|
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list(2个维度)
|
||||||
|
"""
|
||||||
|
yyy = data[0]
|
||||||
|
# print(yyy)
|
||||||
|
list_contours = []
|
||||||
|
for i in range(yyy.shape[0]):
|
||||||
|
list_contours.append([yyy[i][0][0], yyy[i][0][1]])
|
||||||
|
return list_contours
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def scale(data, sec_dis):
|
||||||
|
"""多边形等距缩放
|
||||||
|
Args:
|
||||||
|
data: 多边形按照逆时针顺序排列的的点集
|
||||||
|
sec_dis: 缩放距离
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
缩放后的多边形点集
|
||||||
|
"""
|
||||||
|
num = len(data)
|
||||||
|
scal_data = []
|
||||||
|
for i in range(num):
|
||||||
|
x1 = data[(i) % num][0] - data[(i - 1) % num][0]
|
||||||
|
y1 = data[(i) % num][1] - data[(i - 1) % num][1]
|
||||||
|
x2 = data[(i + 1) % num][0] - data[(i) % num][0]
|
||||||
|
y2 = data[(i + 1) % num][1] - data[(i) % num][1]
|
||||||
|
|
||||||
|
d_A = (x1 ** 2 + y1 ** 2) ** 0.5
|
||||||
|
d_B = (x2 ** 2 + y2 ** 2) ** 0.5
|
||||||
|
|
||||||
|
Vec_Cross = (x1 * y2) - (x2 * y1)
|
||||||
|
if (d_A * d_B==0):
|
||||||
|
continue
|
||||||
|
sin_theta = Vec_Cross / (d_A * d_B)
|
||||||
|
if (sin_theta==0):
|
||||||
|
continue
|
||||||
|
dv = sec_dis / sin_theta
|
||||||
|
|
||||||
|
v1_x = (dv / d_A) * x1
|
||||||
|
v1_y = (dv / d_A) * y1
|
||||||
|
|
||||||
|
v2_x = (dv / d_B) * x2
|
||||||
|
v2_y = (dv / d_B) * y2
|
||||||
|
|
||||||
|
PQ_x = v1_x - v2_x
|
||||||
|
PQ_y = v1_y - v2_y
|
||||||
|
|
||||||
|
Q_x = data[(i) % num][0] + PQ_x
|
||||||
|
Q_y = data[(i) % num][1] + PQ_y
|
||||||
|
scal_data.append([Q_x, Q_y])
|
||||||
|
return scal_data
|
||||||
|
|
||||||
|
# 1.读入图片
|
||||||
|
# img = cv2.imread('demo/171.png')
|
||||||
|
img = cv2.imread('image/171.jpg')
|
||||||
|
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
||||||
|
contours, thresh = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
|
||||||
|
|
||||||
|
# 2.寻找轮廓
|
||||||
|
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_LIST, 2)
|
||||||
|
|
||||||
|
|
||||||
|
list_contours=contours_2_list(contours)
|
||||||
|
|
||||||
|
# for i in range(yyy.shape[0]):
|
||||||
|
# list_contours.append([yyy[i][0][0],yyy[i][0][1]])
|
||||||
|
|
||||||
|
data=list_contours
|
||||||
|
|
||||||
|
|
||||||
|
data1 = scale(data,-150)
|
||||||
|
print(data1)
|
||||||
|
# temp = np.ones((img_gray.shape[0],img_gray.shape[1],3), np.uint8) * 255
|
||||||
|
temp = np.zeros((img_gray.shape[0],img_gray.shape[1],3), np.uint8) * 255
|
||||||
|
# cv2.polylines(temp, data1, 1, 255)
|
||||||
|
cv2.polylines(temp,[np.array(data1, dtype=np.int32)],True, (255, 0, 0), 5)
|
||||||
|
# cv2.polylines(temp , [np.array(data1 , dtype=np.int32)], True, (0, 0, 255), 1)
|
||||||
|
|
||||||
|
cv2.namedWindow("boundary",cv2.WINDOW_NORMAL);
|
||||||
|
cv2.resizeWindow("boundary", 640, 480);
|
||||||
|
cv2.imshow("boundary",temp)
|
||||||
|
|
||||||
|
# cv2.imshow ("img",temp)
|
||||||
|
cv2.imwrite("1.jpg",temp)
|
||||||
|
cv2.waitKey(0)
|
||||||
|
|
@ -0,0 +1,221 @@
|
||||||
|
# -*- coding: UTF-8 -*-
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- encoding: utf-8 -*-
|
||||||
|
'''
|
||||||
|
@File : 多边形等距缩放.py
|
||||||
|
@data :2021/7/5 15:53
|
||||||
|
@Desciption :
|
||||||
|
@Version :
|
||||||
|
@License :
|
||||||
|
'''
|
||||||
|
|
||||||
|
import cv2
|
||||||
|
import numpy as np
|
||||||
|
import time
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def contours_2_list(data):
|
||||||
|
"""将opencv读取的边界numpy数组(3个维度)转化为list(2个维度)
|
||||||
|
Args:
|
||||||
|
data为数组
|
||||||
|
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list(2个维度)
|
||||||
|
"""
|
||||||
|
# yyy = data[0]
|
||||||
|
yyy = data
|
||||||
|
# print(yyy)
|
||||||
|
list_contours = []
|
||||||
|
for i in range(yyy.shape[0]):
|
||||||
|
list_contours.append([yyy[i][0][0], yyy[i][0][1]])
|
||||||
|
return list_contours
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def scale(data, sec_dis):
|
||||||
|
"""多边形等距缩放
|
||||||
|
Args:
|
||||||
|
data: 多边形按照逆时针顺序排列的的点集
|
||||||
|
sec_dis: 缩放距离
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
缩放后的多边形点集
|
||||||
|
"""
|
||||||
|
num = len(data)
|
||||||
|
scal_data = []
|
||||||
|
for i in range(num):
|
||||||
|
x1 = data[(i) % num][0] - data[(i - 1) % num][0]
|
||||||
|
y1 = data[(i) % num][1] - data[(i - 1) % num][1]
|
||||||
|
x2 = data[(i + 1) % num][0] - data[(i) % num][0]
|
||||||
|
y2 = data[(i + 1) % num][1] - data[(i) % num][1]
|
||||||
|
|
||||||
|
d_A = (x1 ** 2 + y1 ** 2) ** 0.5
|
||||||
|
d_B = (x2 ** 2 + y2 ** 2) ** 0.5
|
||||||
|
|
||||||
|
Vec_Cross = (x1 * y2) - (x2 * y1)
|
||||||
|
if (d_A * d_B==0):
|
||||||
|
continue
|
||||||
|
sin_theta = Vec_Cross / (d_A * d_B)
|
||||||
|
if (sin_theta==0):
|
||||||
|
continue
|
||||||
|
dv = sec_dis / sin_theta
|
||||||
|
|
||||||
|
v1_x = (dv / d_A) * x1
|
||||||
|
v1_y = (dv / d_A) * y1
|
||||||
|
|
||||||
|
v2_x = (dv / d_B) * x2
|
||||||
|
v2_y = (dv / d_B) * y2
|
||||||
|
|
||||||
|
PQ_x = v1_x - v2_x
|
||||||
|
PQ_y = v1_y - v2_y
|
||||||
|
|
||||||
|
|
||||||
|
Q_x = data[(i) % num][0] + PQ_x
|
||||||
|
Q_y = data[(i) % num][1] + PQ_y
|
||||||
|
scal_data.append([Q_x, Q_y])
|
||||||
|
return scal_data
|
||||||
|
|
||||||
|
|
||||||
|
t1=time.time()
|
||||||
|
# 1.读入图片
|
||||||
|
# img = cv2.imread('demo/171.png')
|
||||||
|
img = cv2.imread('demo1/10.png')
|
||||||
|
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
||||||
|
t2=time.time()
|
||||||
|
contours, thresh = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
|
||||||
|
|
||||||
|
# 2.寻找轮廓(多边界)
|
||||||
|
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_LIST, 2)
|
||||||
|
t3=time.time()
|
||||||
|
|
||||||
|
# 3.轮廓数组转为列表(多边界)
|
||||||
|
list_contours=[]
|
||||||
|
# xxx=contours[0]
|
||||||
|
# yyy=contours[1]
|
||||||
|
|
||||||
|
for i in range(len(contours)):
|
||||||
|
list_contours.append(contours_2_list(contours[i]))
|
||||||
|
|
||||||
|
# for i in range(yyy.shape[0]):
|
||||||
|
# list_contours.append([yyy[i][0][0],yyy[i][0][1]])
|
||||||
|
|
||||||
|
data=list_contours
|
||||||
|
# 4.等距离扩大或缩小(多边界)
|
||||||
|
data1=[]
|
||||||
|
for i in range(len(data)):
|
||||||
|
data1.append(scale(data[i],-15)) #减号是往外扩
|
||||||
|
print(data1)
|
||||||
|
t4=time.time()
|
||||||
|
|
||||||
|
|
||||||
|
# 5.在原图尺寸上绘制出扩充后边界(多边界)
|
||||||
|
# temp = np.ones((img_gray.shape[0],img_gray.shape[1],3), np.uint8) * 255 #白色底图
|
||||||
|
# temp = np.zeros((img_gray.shape[0],img_gray.shape[1],3), np.uint8) * 255 #黑色底图
|
||||||
|
temp = cv2.imread('demo1/10.jpg') #原图
|
||||||
|
t5=time.time()
|
||||||
|
# cv2.polylines(temp, data1, 1, 255)
|
||||||
|
# cv2.polylines(temp,[np.array(data1, dtype=np.int32)],True, (255, 0, 0), 1,lineType=cv2.LINE_AA)
|
||||||
|
for i in range(len(data1)):
|
||||||
|
cv2.polylines(temp,[np.array(data1[i], dtype=np.int32)],True, (255, 0, 255), 5)
|
||||||
|
# cv2.polylines(temp , [np.array(data1 , dtype=np.int32)], True, (0, 0, 255), 1)\
|
||||||
|
|
||||||
|
t6=time.time()
|
||||||
|
|
||||||
|
cv2.namedWindow("boundary",cv2.WINDOW_NORMAL);
|
||||||
|
cv2.resizeWindow("boundary", 640, 480);
|
||||||
|
cv2.imshow("boundary",temp);
|
||||||
|
cv2.imwrite("demo1/24_detected.jpg",temp)
|
||||||
|
t7=time.time()
|
||||||
|
|
||||||
|
print('总耗时',t7-t1)
|
||||||
|
print("读二值图像耗时:%s 形成轮廓耗时:%s 等距离缩放耗时:%s 读取原图:%s 绘制多段线: %s 保存图像耗时:%s" %(t2-t1,t3-t2,t4-t3,t5-t4,t6-t5,t7-t6))
|
||||||
|
cv2.waitKey(0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# import os
|
||||||
|
# from flask import Flask, request, redirect, url_for, jsonify
|
||||||
|
# from werkzeug.utils import secure_filename
|
||||||
|
#
|
||||||
|
# import cv2
|
||||||
|
# import numpy as np
|
||||||
|
#
|
||||||
|
# UPLOAD_FOLDER = './images'
|
||||||
|
# CONVERTED_FOLDER = './static'
|
||||||
|
# ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'])
|
||||||
|
#
|
||||||
|
# app = Flask(__name__, static_folder='static', static_url_path='/static')
|
||||||
|
# app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
|
||||||
|
# app.config['CONVERTED_FOLDER'] = CONVERTED_FOLDER
|
||||||
|
#
|
||||||
|
# def allowed_file(filename):
|
||||||
|
# return '.' in filename and \
|
||||||
|
# filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
|
||||||
|
#
|
||||||
|
# @app.route('/', methods=['POST'])
|
||||||
|
# def upload_file():
|
||||||
|
# if request.method == 'POST':
|
||||||
|
# if 'file' not in request.files:
|
||||||
|
# return jsonify(error = 'No file part')
|
||||||
|
# file = request.files['file']
|
||||||
|
#
|
||||||
|
# if file.filename == '':
|
||||||
|
# return jsonify(error = 'No selected file')
|
||||||
|
# if file and allowed_file(file.filename):
|
||||||
|
# filename = secure_filename(file.filename)
|
||||||
|
# file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
|
||||||
|
#
|
||||||
|
# filename_no_ext = file.filename.split('.')[0]
|
||||||
|
#
|
||||||
|
# BLUR = 21
|
||||||
|
# CANNY_THRESH_1 = 1
|
||||||
|
# CANNY_THRESH_2 = 200
|
||||||
|
# MASK_DILATE_ITER = 10
|
||||||
|
# MASK_ERODE_ITER = 10
|
||||||
|
# MASK_COLOR = (0.0,0.0,1.0)
|
||||||
|
#
|
||||||
|
# img = cv2.imread(os.path.join(app.config['UPLOAD_FOLDER'], filename))
|
||||||
|
# gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
|
||||||
|
#
|
||||||
|
# edges = cv2.Canny(gray, CANNY_THRESH_1, CANNY_THRESH_2)
|
||||||
|
# edges = cv2.dilate(edges, None)
|
||||||
|
# edges = cv2.erode(edges, None)
|
||||||
|
#
|
||||||
|
# contour_info = []
|
||||||
|
# img2, contours, _ = cv2.findContours(edges, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
|
||||||
|
# for c in contours:
|
||||||
|
# contour_info.append((
|
||||||
|
# c,
|
||||||
|
# cv2.isContourConvex(c),
|
||||||
|
# cv2.contourArea(c),
|
||||||
|
# ))
|
||||||
|
# contour_info = sorted(contour_info, key=lambda c: c[2], reverse=True)
|
||||||
|
# max_contour = contour_info[0]
|
||||||
|
#
|
||||||
|
# mask = np.zeros(edges.shape)
|
||||||
|
#
|
||||||
|
# cv2.fillConvexPoly(mask, max_contour[0], (255))
|
||||||
|
#
|
||||||
|
# mask = cv2.dilate(mask, None, iterations=MASK_DILATE_ITER)
|
||||||
|
# mask = cv2.erode(mask, None, iterations=MASK_ERODE_ITER)
|
||||||
|
# mask = cv2.GaussianBlur(mask, (BLUR, BLUR), 0)
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# mask_stack = np.dstack([mask]*3)
|
||||||
|
#
|
||||||
|
# mask_stack = mask_stack.astype('float32') / 255.0
|
||||||
|
# img = img.astype('float32') / 255.0
|
||||||
|
#
|
||||||
|
# masked = (mask_stack * img) + ((1-mask_stack) * MASK_COLOR)
|
||||||
|
# masked = (masked * 255).astype('uint8')
|
||||||
|
# c_red, c_green, c_blue = cv2.split(img)
|
||||||
|
# img_a = cv2.merge((c_red, c_green, c_blue, mask.astype('float32') / 255.0))
|
||||||
|
#
|
||||||
|
# cv2.imwrite('./static/' + filename_no_ext + '.png', img_a*255)
|
||||||
|
#
|
||||||
|
# return jsonify(url = os.path.join(app.config['UPLOAD_FOLDER'],filename))
|
||||||
|
#
|
||||||
|
# app.run(host='0.0.0.0',threaded=True)
|
||||||