如何通过针中心绘制垂直轴
How can I draw a vertical axis through needle center
我想在这张图片中画一条通过针(黑色物体)中心的垂直轴。我该怎么做。
以下是我的处理方法。
Threshold the image
Average the image down to 1 row
Stretch the 1 row to full dynamic range so that the darkest x coordinates correspond to the top of the black needle
Get the range of x coordinates and compute the center x coordinate
Draw a vertical line
抱歉,我不太了解 OpenCV。所以这是我使用 ImageMagick 的结果。
(请参阅 OpenCV 代码的附加部分)
输入:
阈值图像
convert img.jpg -threshold 5% img_t5.png
将图像缩小到 1 行(然后放大到 50 行以便可视化)
convert img_t5.png -scale x1! -auto-level +write tmp1.png -scale x50! tmp2.png
仅获取黑色像素的 X 坐标数组并获取第一个和最后一个并计算平均值以获得针的中心
xArr=(`convert tmp1.png txt: | grep "gray(0)" | sed -n 's/^\([^,]*\),.*$//p'`)
num=${#xArr[*]}
last=$((num-1))
firstx=${xArr[0]}
lastx=${xArr[$last]}
centx=`convert xc: -format "%[fx:($firstx+$lastx)/2]" info:`
画红线
convert img.jpg -fill red -draw "line $centx,0 $centx,2047" -alpha off result.jpg
添加:
我对 OpenCV 不是很精通。尽管如此,在花费了相当长的时间之后,这里有一种在 OpenCV 中执行此操作的方法。
import cv2
import numpy as np
# read image
img = cv2.imread('needle.jpg', cv2.IMREAD_UNCHANGED)
#print('Original Dimensions : ',img.shape)
# get dimensions
height = img.shape[0]
width = img.shape[1]
# threshold image
threshold = 5*255/100
ret,thresholded = cv2.threshold(img,threshold,255,cv2.THRESH_BINARY)
# resize image to 1 row
wd = width
ht = 1
dim = (wd, ht)
resized = cv2.resize(thresholded, dim, interpolation = cv2.INTER_AREA)
#print('Resized Dimensions : ',resized.shape)
# stretch values to full dynamic range (0 to 255)
stretched = cv2.normalize(resized,None,0,255,cv2.NORM_MINMAX)
# get x coordinate locations of zeroes (black pixels)
minLocations = list(np.nonzero(stretched==0))[1]
numberLocations = len(minLocations)
print("Zero Locations: ",minLocations)
# get first and last x coordinate values and then the average of first and last values in list
first = minLocations[0]
last = minLocations[numberLocations-1]
average = int(round((first+last)/2))
print("Centerline X Coordinate: ",average)
# draw red line on image
new_img = img.copy()
new_img = cv2.cvtColor(new_img, cv2.COLOR_GRAY2BGR)
cv2.line(new_img,(average,0),(average,height),(0,0,255),1)
# save result
cv2.imwrite("needle_centerline.jpg", new_img)
以下是打印结果:
Zero Locations: [1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287]
Centerline X Coordinate: 1258
Mark Setchell 添加了以下建议,即通过对(阈值)图像的列求和并选择总数最小的列同样可以找到针,因为它具有大多数黑人和最少的白人:
import cv2
import numpy as np
# read image
img = cv2.imread('needle.jpg', cv2.IMREAD_UNCHANGED)
#print('Original Dimensions : ',img.shape)
# get dimensions
height, width = img.shape
# threshold image
threshold = 5*255/100
ret,thresholded = cv2.threshold(img,threshold,255,cv2.THRESH_BINARY)
# Sum up columns to get column totals
ct = np.sum(thresholded,axis=0)
# Find index of column with lowest total, i.e. least white and most black
index = np.argmin(ct)
... continue as Fred
# draw red line on image
new_img = img.copy()
new_img = cv2.cvtColor(new_img, cv2.COLOR_GRAY2BGR)
cv2.line(new_img,(index,0),(index,height),(0,0,255),1)
# save result
cv2.imwrite("needle_centerline.jpg", new_img)
我想在这张图片中画一条通过针(黑色物体)中心的垂直轴。我该怎么做。
以下是我的处理方法。
Threshold the image
Average the image down to 1 row
Stretch the 1 row to full dynamic range so that the darkest x coordinates correspond to the top of the black needle
Get the range of x coordinates and compute the center x coordinate
Draw a vertical line
抱歉,我不太了解 OpenCV。所以这是我使用 ImageMagick 的结果。
(请参阅 OpenCV 代码的附加部分)
输入:
阈值图像
convert img.jpg -threshold 5% img_t5.png
将图像缩小到 1 行(然后放大到 50 行以便可视化)
convert img_t5.png -scale x1! -auto-level +write tmp1.png -scale x50! tmp2.png
仅获取黑色像素的 X 坐标数组并获取第一个和最后一个并计算平均值以获得针的中心
xArr=(`convert tmp1.png txt: | grep "gray(0)" | sed -n 's/^\([^,]*\),.*$//p'`)
num=${#xArr[*]}
last=$((num-1))
firstx=${xArr[0]}
lastx=${xArr[$last]}
centx=`convert xc: -format "%[fx:($firstx+$lastx)/2]" info:`
画红线
convert img.jpg -fill red -draw "line $centx,0 $centx,2047" -alpha off result.jpg
添加:
我对 OpenCV 不是很精通。尽管如此,在花费了相当长的时间之后,这里有一种在 OpenCV 中执行此操作的方法。
import cv2
import numpy as np
# read image
img = cv2.imread('needle.jpg', cv2.IMREAD_UNCHANGED)
#print('Original Dimensions : ',img.shape)
# get dimensions
height = img.shape[0]
width = img.shape[1]
# threshold image
threshold = 5*255/100
ret,thresholded = cv2.threshold(img,threshold,255,cv2.THRESH_BINARY)
# resize image to 1 row
wd = width
ht = 1
dim = (wd, ht)
resized = cv2.resize(thresholded, dim, interpolation = cv2.INTER_AREA)
#print('Resized Dimensions : ',resized.shape)
# stretch values to full dynamic range (0 to 255)
stretched = cv2.normalize(resized,None,0,255,cv2.NORM_MINMAX)
# get x coordinate locations of zeroes (black pixels)
minLocations = list(np.nonzero(stretched==0))[1]
numberLocations = len(minLocations)
print("Zero Locations: ",minLocations)
# get first and last x coordinate values and then the average of first and last values in list
first = minLocations[0]
last = minLocations[numberLocations-1]
average = int(round((first+last)/2))
print("Centerline X Coordinate: ",average)
# draw red line on image
new_img = img.copy()
new_img = cv2.cvtColor(new_img, cv2.COLOR_GRAY2BGR)
cv2.line(new_img,(average,0),(average,height),(0,0,255),1)
# save result
cv2.imwrite("needle_centerline.jpg", new_img)
以下是打印结果:
Zero Locations: [1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287]
Centerline X Coordinate: 1258
Mark Setchell 添加了以下建议,即通过对(阈值)图像的列求和并选择总数最小的列同样可以找到针,因为它具有大多数黑人和最少的白人:
import cv2
import numpy as np
# read image
img = cv2.imread('needle.jpg', cv2.IMREAD_UNCHANGED)
#print('Original Dimensions : ',img.shape)
# get dimensions
height, width = img.shape
# threshold image
threshold = 5*255/100
ret,thresholded = cv2.threshold(img,threshold,255,cv2.THRESH_BINARY)
# Sum up columns to get column totals
ct = np.sum(thresholded,axis=0)
# Find index of column with lowest total, i.e. least white and most black
index = np.argmin(ct)
... continue as Fred
# draw red line on image
new_img = img.copy()
new_img = cv2.cvtColor(new_img, cv2.COLOR_GRAY2BGR)
cv2.line(new_img,(index,0),(index,height),(0,0,255),1)
# save result
cv2.imwrite("needle_centerline.jpg", new_img)