python - 收集所有不同轮廓的非零像素
问题描述
我一直在尝试根据序列对轮廓进行排序(序列在这里无关紧要)。我有一个非常小的问题,这是我应该在下面的代码片段中传递的正确的 numpy 数组,我可以同时获得正确的行/列(非零)像素。
row_pixels=cv2.countNonZero(blur[cy][:])
col_pixels=cv2.countNonZero(blur[:,cx])
我所做的结果如下所示:对于所有 5 个轮廓,我得到几乎相同数量的非零像素,我意识到这是因为我正在传递“整个”图像(如您在上面看到的那样,模糊是整个图像)为用于计算错误像素的 numpy 数组,我意识到这一点。
当前输入:下图(无标记)
预期输出:对于所有 5 个轮廓,行/列(非零)像素。
我目前正在做的是:
import cv2
import numpy as np
from imutils import perspective
from imutils import contours
import imutils
from scipy.spatial import distance as dist
import argparse
import pandas as pd
import time
parser = argparse.ArgumentParser(description='Object Detection and Tracking using YOLO in OPENCV')
parser.add_argument('--image', help='Path to image file.')
args = parser.parse_args()
font=cv2.FONT_HERSHEY_SIMPLEX
start=time.time()
im_in = cv2.imread(args.image, 0)
_, thres2=cv2.threshold(im_in, 140, 255,cv2.THRESH_BINARY_INV)
dilate = cv2.dilate(thres2,None)
erode = cv2.erode(dilate,None)
im_3=erode.copy()
blur=cv2.medianBlur(im_3,5)
a=[]
r=[]
row_col_pixel_values=[]
cl=[]
data=[]
global mainar
#find contours
_,contour2,_=cv2.findContours(blur,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_NONE)
# print(contour2)
for c in contour2:
area=cv2.contourArea(c)
if area>10000 and area <30000:
a.append(area)
cv2.drawContours(blur, [c], 0, (128, 128, 128), 1)
M=cv2.moments(c)
cx=int((M["m10"]/M["m00"]))
cy=int((M["m01"]/M["m00"]))
center =(cx,cy)
data.append((cx,cy))
cv2.circle(blur,(cx,cy), 5,(128,128,128),-1)
print("",cx,cy)
print(len(blur[cy][:]))
# one=blur[c]
row_pixels=cv2.countNonZero(blur[cy][:])
col_pixels=cv2.countNonZero(blur[:,cx])
comb=(row_pixels,col_pixels)
cl.append(comb)
nparea=np.array(a)
npcentercoord=np.array(data)
row_col_pixel_values=np.array(cl)
print("Area of 5 contours :",nparea)
print("Center coordinates of 5 contours:",npcentercoord)
print("Row and Column pixel values of 5 contours:",row_col_pixel_values)
mainar=np.column_stack((nparea,npcentercoord,row_col_pixel_values))
# print(mainar)
mainar[:,[1]] = (mainar[:,[1]]).astype(int)
MinX = int(min([_[1] for _ in mainar]))
MinlowerX = (MinX - 10)
MinupperX = (MinX + 10)
MinY = int(min([_[2] for _ in mainar]))
MinlowerY = (MinY - 10)
MinupperY = (MinY + 10)
MaxX = int(max([_[1] for _ in mainar]))
MaxlowerX = (MaxX - 10)
MaxupperX = (MaxX + 10)
MaxY = int(max([_[2] for _ in mainar]))
MaxlowerY = (MaxY - 10)
MaxupperY = (MaxY + 10)
print("", MinX,MinY,MaxX,MaxY)
def PixeltoNumeric(channel,rowMM,colMM):
if channel=="4S":
for i in range(0, len(mainar[:,1])):
cx=mainar[i,1]
cy=mainar[i,2]
if (cx in range(MinlowerX,MinupperX+1)) and (cy in range(MinlowerY,MinupperY+1)):
rowp=mainar[i,3]
colp=mainar[i,4]
print("The center coordinates(x,y) and (Row/Col) pixels of 4Schannel: ")
print("1 pixel has {:.5f} many mm in row:".format(rowMM/rowp))
print("1 pixel has {:.5f} many mm in col:".format(colMM/colp))
print(cx,cy,rowp,colp)
if channel == '1':
for i in range(0, len(mainar[:,1])):
cx=mainar[i,1]
cy=mainar[i,2]
if (cx in range(MaxlowerX,MaxupperX+1)) and (cy in range(MaxlowerY,MaxupperY+1)):
rowp=mainar[i,3]
colp=mainar[i,4]
print("The center coordinates(x,y) and (Row/Col) pixels of 1Channel: ")
print("1 pixel has {:.5f} many mm in row:".format(rowMM/rowp))
print("1 pixel has {:.5f} many mm in col:".format(colMM/colp))
print(cx,cy,rowp,colp)
if channel == '2':
for i in range(0, len(mainar[:,1])):
cx=mainar[i,1]
cy=mainar[i,2]
if (cx in range(MinlowerX,MinupperX+1)) and (cy in range(MaxlowerY,MaxupperY+1)):
rowp=mainar[i,3]
colp=mainar[i,4]
print("The center coordinates(x,y) and (Row/Col) pixels of 2Channel: ")
print("1 pixel has {:.5f} many mm in row:".format(rowMM/rowp))
print("1 pixel has {:.5f} many mm in col:".format(colMM/colp))
print(cx,cy,rowp,colp)
if channel == '3':
for i in range(0, len(mainar[:,1])):
cx=mainar[i,1]
cy=mainar[i,2]
if (cx in range(((MinlowerX+MaxlowerX)//2),((MinupperX+MaxupperX+1)//2)) and (cy in range(((MinlowerY+MaxlowerY)//2),((MinupperY+MaxupperY+1)//2)))):
rowp=mainar[i,3]
colp=mainar[i,4]
print("The center coordinates(x,y) and (Row/Col) pixels of 3Channel: ")
print("1 pixel has {:.5f} many mm in row:".format(rowMM/rowp))
print("1 pixel has {:.5f} many mm in col:".format(colMM/colp))
print(cx,cy,rowp,colp)
if channel == '4N':
for i in range(0, len(mainar[:,1])):
cx=mainar[i,1]
cy=mainar[i,2]
if (cx in range(MaxlowerX,MaxupperX+1)) and (cy in range(MinlowerY,MinupperY+1)):
rowp=mainar[i,3]
colp=mainar[i,4]
print("The center coordinates(x,y) and (Row/Col) pixels of 4NChannel: ")
print("1 pixel has {:.5f} many mm in row:".format(rowMM/rowp))
print("1 pixel has {:.5f} many mm in col:".format(colMM/colp))
print(cx,cy,rowp,colp)
return (cv2.imshow("4",blur))
cv2.waitKey(0)
cv2.destroyAllWindows()
解决方案
我不完全确定我是否正确理解你,但我的理解是你想找到所有轮廓内像素的所有坐标(x,y)。如果这是您的问题,您可以使用以下代码实现:
import cv2
import matplotlib.pyplot as plt
import numpy as np
im_in = cv2.imread(r'image.png', 0)
_, thres2 = cv2.threshold(im_in, 140, 255, cv2.THRESH_BINARY_INV)
dilate = cv2.dilate(thres2, None)
erode = cv2.erode(dilate, None)
im_3 = erode.copy()
blur = cv2.medianBlur(im_3, 5)
# I am using OpenCV 4 therefore it returns only 4 parameters
contour2, _ = cv2.findContours(blur, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)
extracted = np.zeros(blur.shape, np.uint8)
for c in contour2:
area = cv2.contourArea(c)
# I have modified these values to make it work for attached picture
if 10000 < area < 300000:
cv2.drawContours(extracted, [c], 0, (255), cv2.FILLED)
contour_x, contour_y = np.nonzero(extracted)
plt.imshow(extracted, 'gray')
plt.show()
这是提取的图像。
更新 1
经过您的解释,我了解到您想要计算每个单独轮廓的宽度和高度。根据您提供的示例代码,我假设您想使用穿过轮廓中心的线来测量宽度和高度。您可以通过在清晰图像上绘制和测量轮廓来实现。请看下面的代码:
# I am using OpenCV 4 therefore it returns only 4 parameters
contour2, _ = cv2.findContours(blur, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)
extracted = np.zeros(blur.shape, np.uint8)
contoursSize = []
for c in contour2:
area = cv2.contourArea(c)
# I have modified these values to make it work for attached picture
if 10000 < area < 300000:
M = cv2.moments(c)
cx = int((M["m10"] / M["m00"]))
cy = int((M["m01"] / M["m00"]))
extracted.fill(0)
cv2.drawContours(extracted, [c], 0, 255, cv2.FILLED)
width = cv2.countNonZero(extracted[cy][:])
height = cv2.countNonZero(extracted[:, cx])
contoursSize.append((width, height))
推荐阅读
- python - 您可以像使用 SBOP Analysis for Excel 一样使用 Python 连接到 SAP Query 吗?
- azerothcore - 已经有现有的 MariaDB docker 容器 - 我如何编译 world 和 auth 服务器以使用它而不是构建 db 容器
- python - 在函数末尾使用 return 1 或 -1 有什么必要?
- certificate - 签署证书问题
- python - 从mongo到值数组的json响应
- java - python 是否有异步 Web 客户端请求(如 C# async/await)?还是每个调用基本上是同步的(如 Java 1.8)?
- python - 熊猫数据框列拆分
- python - 无法在 csv 文件中写入结果略有不同
- r - 根据两个变量的确切时间差在分组数据集中有条件地创建变量
- c - 如何鼓励对链接器变量的“地址”访问