gpt4 book ai didi

python - 将内切圆绘制成阈值图像

转载 作者:行者123 更新时间:2023-12-02 16:19:46 24 4
gpt4 key购买 nike

我正在尝试将最大内切圆绘制到阈值(轮廓)图像中以提取手的手掌部分。

原图 1 :

enter image description here

我的代码:

import cv2
import imutils

pathToThePhoto = 'hand.jpg'

#Load the photo
img = cv2.imread(pathToThePhoto)

#Converting the image into gray colour
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

#Thresholding the image
thresh = cv2.threshold(gray, 100 , 255, cv2.THRESH_BINARY)[1]

cv2.imshow("thresholded", thresh)

enter image description here
#Find contours in thresholded image
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)

#Draw the contours into the gray image
c = max(cnts, key=cv2.contourArea)
mask = cv2.drawContours(gray, [c], -1, (0,255,0), 2)

cv2.imshow("contours", mask)

enter image description here
#Apply the distance transform for mask 
out = cv2.distanceTransform(mask, distanceType=cv2.DIST_L2, maskSize=5)
out = cv2.normalize(out, out, 0.0, 1.0, cv2.NORM_L2)

cv2.imshow("distanceTransform", out)

enter image description here
#Get the information about position 
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(out) #Actual values 0.0 0.0 (0, 0) (0, 0)

#Draw the circle into original image
img = cv2.circle(img, max_loc , int(max_val) , (255, 255, 0), 10)

cv2.imshow("img_with_circle", img)

enter image description here

完整代码:
import cv2
import imutils

pathToThePhoto = 'hand.jpg'

img = cv2.imread(pathToThePhoto)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 100 , 255, cv2.THRESH_BINARY)[1]

cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)

c = max(cnts, key=cv2.contourArea)
mask = cv2.drawContours(gray, [c], -1, (0,255,0), 2)
out = cv2.distanceTransform(mask, distanceType=cv2.DIST_L2, maskSize=5)
out = cv2.normalize(out, out, 0.0, 1.0, cv2.NORM_L2)

min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(out)

print(min_val, max_val, min_loc, max_loc)
img = cv2.circle(img, max_loc , int(max_val) , (255, 255, 0), 10)

cv2.imshow("thresholded", thresh)
cv2.imshow("contours", mask)
cv2.imshow("distanceTransform", out)
cv2.imshow("img_with_circle", img)

cv2.waitKey(0)
cv2.destroyAllWindows()

结果应该是:

enter image description here

但是 distanceTransform 函数不起作用。怎么了?

1 Ajay Kumar. IIT Delhi Palmprint Image Database version 1.0. 2007

最佳答案

distanceTransform 假设 0 输入 = 0 距离。不确定它是否适用于您的输入图像(在您绘制黑色轮廓的地方,我通常使用蒙版作为输入。

这是 C++ 代码,但它类似于您的 python 代码,但使用带有实线绘制的最大轮廓的蒙版作为距离变换的输入:

int main()
{
cv::Mat in = cv::imread("C:/StackOverflow/Input/dtInput.png", cv::IMREAD_GRAYSCALE);

std::vector<std::vector<cv::Point> > contours;
cv::findContours(in.clone(), contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);

if (contours.size() == 0) return 0;
int cIndex = 0;

for (int i = 1; i < contours.size(); ++i)
{
if (cv::contourArea(contours[i]) > cv::contourArea(contours[cIndex]))
cIndex = i;
}

cv::Mat tmp = cv::Mat::zeros(in.size(), CV_8UC1);
cv::drawContours(tmp, contours, cIndex, cv::Scalar::all(255), -1);

cv::Mat dist;

cv::distanceTransform(tmp, dist, CV_DIST_L2, 5);

double minVal, maxVal;
cv::Point minLoc, maxLoc;
cv::minMaxLoc(dist, &minVal, &maxVal, &minLoc, &maxLoc);


cv::Mat bgr;
cv::cvtColor(in, bgr, cv::COLOR_GRAY2BGR);
cv::circle(bgr, maxLoc, maxVal, cv::Scalar(0, 0, 255), 3);

cv::imshow("dist", 1.0/255.0 *dist);
cv::imshow("result", bgr);


cv::imwrite("C:/StackOverflow/Input/dtInput_res.png", bgr);
cv::imwrite("C:/StackOverflow/Input/dtInput_dt.png", dist);

cv::waitKey(0);
}

给出这些结果:

dt 输入:

enter image description here

距离变换:

enter image description here

结果:

enter image description here

关于python - 将内切圆绘制成阈值图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61211151/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com