这是一个可能的解决方案。基本上,我检测原始图像上的四个斑点,获取它们的边界框并计算它们的质心。我用质心到flood-fill这个位置用黑色,然后在同一个位置画一个像素。
但是,您的图像是巨大且压缩的。我调整了它的大小(如果你不想调整它的大小,你可以将scalePercent 保留在100),将其转换为grayscale 然后threshold 它 - 正如我所说,你的图像被压缩并且一些像素不是真正的白色,因此阈值处理给了我一个真正的二值图像:
# imports:
import cv2
# Set image path
imagePath = "C://opencvImages//"
imageName = "juPHJ.jpg"
# Read image:
inputImage = cv2.imread(imagePath + imageName)
# Resize percent:
scalePercent = 20
# Calculate new dimensions:
newWidth = int(inputImage.shape[1] * scalePercent / 100)
newHeight = int(inputImage.shape[0] * scalePercent / 100)
# Resize image
inputImage = cv2.resize(inputImage, (newWidth, newHeight))
# Input deep copy
inputCopy = inputImage.copy()
# Convert BGR to grayscale:
grayInput = cv2.cvtColor(inputImage, cv2.COLOR_BGR2GRAY)
# Get binary image via Otsu:
_, binaryImage = cv2.threshold(grayInput, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
现在,让我们提取白色斑点,获取它们的边界框,计算质心并相应地计算flood-fill:
# Extract blobs:
contours, _ = cv2.findContours(binaryImage, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Loop through the blobs, get their bounding boxes:
for i, c in enumerate(contours):
# Get blob bounding box:
x, y, w, h = cv2.boundingRect(c)
# Compute centroid:
cx = int(x + 0.5 * w)
cy = int(y + 0.5 * h)
# Flood-fill at the center:
fillPosition = (cx, cy)
fillColor = (0, 0, 0)
cv2.floodFill(binaryImage, None, fillPosition, fillColor, loDiff=(10, 10, 10), upDiff=(10, 10, 10))
# Draw a pixel at the center:
binaryImage[cy, cx] = 255
# Show new Image:
cv2.imshow("New Image", binaryImage)
cv2.waitKey(0)
这是输出(不过,您必须真正放大才能看到单个像素):