python - How to extract an intensity profile along a line?
问题描述
Is there an out-of-the-box funcion in OpenCV to extract an intensity profile from an image along a line, something like the improfile
function in MATLAB?
解决方案
Here comes a small, interactive Python application to mimic MATLAB's improfile
.
An image is loaded, and shown in an OpenCV window. Mouse button down and up events are recorded to get the line's start and end. The line (white) is shown in the image, and the corresponding RGB intensity profiles are shown in an addition Matplotlib window. The infinite loop can be exited by pressing the c
key within the OpenCV window.
Here's how it looks:
And, here comes the code:
import cv2
from matplotlib import pyplot as plt
import numpy as np
from skimage import draw
# Actual mouse callback function
def print_coords(event, x, y, flags, param):
# Global variables needed
global image, image_copy, r_start, c_start
# If left mouse button is clicked, start of line
if (event == cv2.EVENT_LBUTTONDOWN):
r_start = x
c_start = y
# If left mouse button is clicked, end of line; plot intensity profile
if (event == cv2.EVENT_LBUTTONUP):
r_end = x
c_end = y
image = cv2.line(image_copy.copy(), (r_start, c_start), (r_end, c_end), (255, 255, 255), 2)
line = np.transpose(np.array(draw.line(r_start, c_start, r_end, c_end)))
data = image_copy.copy()[line[:, 1], line[:, 0], :]
plt.close()
plt.figure('Intensity profile')
plt.plot(data[:, 0], 'b', data[:, 1], 'g', data[:, 2], 'r')
plt.draw()
plt.pause(0.001)
plt.legend(['Blue', 'Green', 'Red'])
plt.ylim((0, 255))
# Read an image
image = cv2.imread('path/to/your/image.png', cv2.IMREAD_COLOR)
image_copy = image.copy()
# Set up window and mouse callback function
cv2.namedWindow("image")
cv2.setMouseCallback("image", print_coords)
# Loop until the 'c' key is pressed
while True:
# Display image; wait for keypress
cv2.imshow("image", image)
key = cv2.waitKey(1) & 0xFF
# If 'c' key is pressed, break from loop
if key == ord("c"):
break
cv2.destroyAllWindows()
To get the coordinates of the line, I use the line
function from scikit-image. That seems to be fastest Pythonic way.
Hope that helps the Python people looking for such a functionality!
推荐阅读
- php - 以概率选择 RAND()
- php - 怎样才能获得价值?结果如下: Array ( [] => 2018 )
- android - 与 Firebase 相关的 Android 清单合并错误
- javascript - 为什么 JavaScript Date 构造函数在这个数字上失败,但作为一种方法工作得很好
- kubernetes - 如何更改 Kubernetes 中运行的 Pod 限制?
- r - 拟合曲线时对参数施加条件
- apache-camel - Apache Camel:发送参数直接
- c# - 如何仅通过登录身份验证表单才能打开 exe 文件
- mongodb - 在 mongodb 中聚合查询结果
- c - C libcurl 小于预期的响应大小