如何计算边缘的平均偏差和标准偏差(OpenCV 中的 Canny 边缘检测)
How to compute Mean and Standard Deviation of Edges (Canny Edge Detection in OpenCV)
我有一些图像,您可以在其中看到打印的半色调,我想计算这些点的平均值和标准差。
我正在使用 OpenCV 和 Canny 边缘检测来隔离这样的点
import cv2
img = cv2.imread('img/color_dots.png')
img_blur = cv2.GaussianBlur(img, (3,3), 0)
edges = cv2.Canny(image=img_blur, threshold1=50, threshold2=100)
这是原图:
这里是精巧的边缘图像:
我认为并不是所有的点都能被识别出来,尤其是黄色的...
而且我不确定我的方法是否适用于边缘检测或更好地找到轮廓?
无论如何,我如何计算这些点的平均大小?
这是 Python/OpenCV 中的一种方法。
阈值背景以隔离点。然后,您可以使用遮罩直接在 OpenCV 中计算颜色的平均值。然后可以从方差的平方根得到标准差,它是图像平方的均值减去图像均值的平方。参见 https://en.wikipedia.org/wiki/Standard_deviation
(或者,使用 Numpy 直接从 np.mean 和 np.std 计算均值和标准差)
输入:
import cv2
import numpy as np
img = cv2.imread("color_dots.png")
# threshold on background color
lower = (215,215,215)
upper = (255,255,255)
thresh = cv2.inRange(img, lower, upper)
# invert so dots are white
thresh = 255 - thresh
#thresh = cv2.cvtColor(thresh, cv2.COLOR_GRAY2BGR)
# get mean colors of dots using mask
mean_values = cv2.mean(img, mask=thresh)[0:3]
mean_values = list(mean_values)
print("mean:", mean_values)
# compute square of image (as floats) and compute mean of squared image
imgf = img.astype(np.float64)
imgf2 = imgf * imgf
mean2_values = cv2.mean(imgf2, mask=thresh)[0:3]
# convert mean of image and mean of image squared tuples to arrays
mean_values_arr = np.array([mean_values])
mean2_values_arr = np.array([mean2_values])
# compute the variance from the mean of image and mean of image squared arrays
variance_values_arr = mean2_values_arr - (mean_values_arr)*(mean_values_arr)
# compute sqrt to form std
std_values_arr = np.sqrt(variance_values_arr)
# convert array to simple list
std_values = list(std_values_arr[0])
print("std:", std_values)
# save result
cv2.imwrite("color_dots_threshold.png",thresh)
cv2.imshow("thresh", thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()
阈值图像:
均值和标准差:
mean: [226.75895493644884, 209.73003594813198, 212.56531647194763]
std: [21.657486571574186, 19.53005158116894, 30.588081007741454]
加法
这是使用 Numpy 的另一种更直接的方法。
import cv2
import numpy as np
img = cv2.imread("color_dots.png")
# threshold on background color
lower = (215,215,215)
upper = (255,255,255)
thresh = cv2.inRange(img, lower, upper)
# invert so dots are white
thresh = 255 - thresh
# separate channels
b,g,r = cv2.split(img)
# compute mean of each channel
bmean = np.mean(b[np.where(thresh==255)])
gmean = np.mean(g[np.where(thresh==255)])
rmean = np.mean(r[np.where(thresh==255)])
# compute std of each channel
bstd = np.std(b[np.where(thresh==255)])
gstd = np.std(g[np.where(thresh==255)])
rstd = np.std(r[np.where(thresh==255)])
# print results
print("mean:", bmean,gmean,rmean)
print("std:", bstd,gstd,rstd)
# save result
cv2.imwrite("color_dots_threshold.png",thresh)
cv2.imshow("thresh", thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()
均值和标准差:
mean: 226.75895493644884 209.73003594813198 212.56531647194763
std: 21.657486571574225 19.53005158116893 30.58808100774145
加法 2
这可能是使用 OpenCV 的最简单方法。
import cv2
import numpy as np
img = cv2.imread("color_dots.png")
# threshold on background color
lower = (215,215,215)
upper = (255,255,255)
thresh = cv2.inRange(img, lower, upper)
# invert so dots are white
thresh = 255 - thresh
# compute mean and standard deviation
mean, std = cv2.meanStd(img, mask=thresh)[0:3]
# print results
print("mean:", mean)
print("std:", std)
# save result
cv2.imwrite("color_dots_threshold.png",thresh)
cv2.imshow("thresh", thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()
均值和标准差:
mean: 226.75895493644884 209.73003594813198 212.56531647194763
std: 21.657486571574225 19.53005158116893 30.58808100774145
我有一些图像,您可以在其中看到打印的半色调,我想计算这些点的平均值和标准差。 我正在使用 OpenCV 和 Canny 边缘检测来隔离这样的点
import cv2
img = cv2.imread('img/color_dots.png')
img_blur = cv2.GaussianBlur(img, (3,3), 0)
edges = cv2.Canny(image=img_blur, threshold1=50, threshold2=100)
这是原图:
这里是精巧的边缘图像:
我认为并不是所有的点都能被识别出来,尤其是黄色的... 而且我不确定我的方法是否适用于边缘检测或更好地找到轮廓? 无论如何,我如何计算这些点的平均大小?
这是 Python/OpenCV 中的一种方法。
阈值背景以隔离点。然后,您可以使用遮罩直接在 OpenCV 中计算颜色的平均值。然后可以从方差的平方根得到标准差,它是图像平方的均值减去图像均值的平方。参见 https://en.wikipedia.org/wiki/Standard_deviation
(或者,使用 Numpy 直接从 np.mean 和 np.std 计算均值和标准差)
输入:
import cv2
import numpy as np
img = cv2.imread("color_dots.png")
# threshold on background color
lower = (215,215,215)
upper = (255,255,255)
thresh = cv2.inRange(img, lower, upper)
# invert so dots are white
thresh = 255 - thresh
#thresh = cv2.cvtColor(thresh, cv2.COLOR_GRAY2BGR)
# get mean colors of dots using mask
mean_values = cv2.mean(img, mask=thresh)[0:3]
mean_values = list(mean_values)
print("mean:", mean_values)
# compute square of image (as floats) and compute mean of squared image
imgf = img.astype(np.float64)
imgf2 = imgf * imgf
mean2_values = cv2.mean(imgf2, mask=thresh)[0:3]
# convert mean of image and mean of image squared tuples to arrays
mean_values_arr = np.array([mean_values])
mean2_values_arr = np.array([mean2_values])
# compute the variance from the mean of image and mean of image squared arrays
variance_values_arr = mean2_values_arr - (mean_values_arr)*(mean_values_arr)
# compute sqrt to form std
std_values_arr = np.sqrt(variance_values_arr)
# convert array to simple list
std_values = list(std_values_arr[0])
print("std:", std_values)
# save result
cv2.imwrite("color_dots_threshold.png",thresh)
cv2.imshow("thresh", thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()
阈值图像:
均值和标准差:
mean: [226.75895493644884, 209.73003594813198, 212.56531647194763]
std: [21.657486571574186, 19.53005158116894, 30.588081007741454]
加法
这是使用 Numpy 的另一种更直接的方法。
import cv2
import numpy as np
img = cv2.imread("color_dots.png")
# threshold on background color
lower = (215,215,215)
upper = (255,255,255)
thresh = cv2.inRange(img, lower, upper)
# invert so dots are white
thresh = 255 - thresh
# separate channels
b,g,r = cv2.split(img)
# compute mean of each channel
bmean = np.mean(b[np.where(thresh==255)])
gmean = np.mean(g[np.where(thresh==255)])
rmean = np.mean(r[np.where(thresh==255)])
# compute std of each channel
bstd = np.std(b[np.where(thresh==255)])
gstd = np.std(g[np.where(thresh==255)])
rstd = np.std(r[np.where(thresh==255)])
# print results
print("mean:", bmean,gmean,rmean)
print("std:", bstd,gstd,rstd)
# save result
cv2.imwrite("color_dots_threshold.png",thresh)
cv2.imshow("thresh", thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()
均值和标准差:
mean: 226.75895493644884 209.73003594813198 212.56531647194763
std: 21.657486571574225 19.53005158116893 30.58808100774145
加法 2
这可能是使用 OpenCV 的最简单方法。
import cv2
import numpy as np
img = cv2.imread("color_dots.png")
# threshold on background color
lower = (215,215,215)
upper = (255,255,255)
thresh = cv2.inRange(img, lower, upper)
# invert so dots are white
thresh = 255 - thresh
# compute mean and standard deviation
mean, std = cv2.meanStd(img, mask=thresh)[0:3]
# print results
print("mean:", mean)
print("std:", std)
# save result
cv2.imwrite("color_dots_threshold.png",thresh)
cv2.imshow("thresh", thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()
均值和标准差:
mean: 226.75895493644884 209.73003594813198 212.56531647194763
std: 21.657486571574225 19.53005158116893 30.58808100774145