使用OpenCV处理图像时红色像素旋转90度的问题排查请求
问题:图像白色像素转红色后位置旋转90度
尝试将图像中所有白色像素转换为红色,但运行程序后,图像形状正常,但红色像素整体旋转了90度(结果图显示原图像的白色区域被替换为红色,但红色区域的位置相对于原白色区域旋转了90度)。
原代码
import cv2 as cv import numpy as np import os from matplotlib import pyplot as plt import cv2 as cv def get_white_pixels(image_as_array): threshold = 40 indices = np.where(image_as_array >= threshold) width=image.shape[1] height=image.shape[0] cartesian_y=height-indices[0]-1 np_data_points=np.column_stack((indices[1],cartesian_y)) return cartesian_y, np_data_points, width,height image = cv.imread("framenumber0.jpg") ind, pixels, width, height = get_white_pixels(image) #Goes through every pixel and changes its values for i in range(0, len(pixels)): loc_x = int(pixels[i][0]) loc_y = int(pixels[i][1]) image[loc_x,loc_y] = (0,0,255) cv.imshow('Modified Image', image) cv.waitKey(0) cv.destroyAllWindows()
我需要保留白色像素的位置用于项目第二部分,怀疑问题和np.column_stack()有关,但看文档后还是不明白原因。源图像为深色背景上带有白色数字的图像。
问题原因及修复
核心问题:OpenCV图像的索引顺序搞反了
OpenCV读取的图像数组形状是(高度, 宽度, 通道数),也就是说访问像素时的顺序是image[y坐标, x坐标],但你在赋值时用了image[loc_x, loc_y],把x和y的位置颠倒了,这直接导致了像素位置旋转90度的问题。
其他隐藏问题:
- 函数内使用全局变量:
get_white_pixels函数里用了全局的image.shape,而不是传入的image_as_array.shape,这会导致如果传入其他图像时出错。 - 三通道图像的阈值判断错误:直接对三通道图像做
image_as_array >= threshold会得到三维布尔数组,np.where返回的索引会包含三个维度的信息,导致获取的像素位置有误。应该先将图像转为灰度图再判断,或者判断三个通道都满足阈值条件。
修正后的代码
import cv2 as cv import numpy as np def get_white_pixels(image): threshold = 40 # 转为灰度图处理白色像素判断 gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY) # 获取灰度图中大于阈值的像素索引(对应白色/亮区域) y_indices, x_indices = np.where(gray >= threshold) height, width = image.shape[:2] # 转换为笛卡尔坐标(原点在左下角) cartesian_y = height - y_indices - 1 # 存储(x, 笛卡尔y)格式的坐标 np_data_points = np.column_stack((x_indices, cartesian_y)) return cartesian_y, np_data_points, width, height image = cv.imread("framenumber0.jpg") # 复制原图像避免修改原图(可选,根据需求调整) modified_image = image.copy() ind, pixels, width, height = get_white_pixels(modified_image) # 遍历像素修改颜色:注意索引顺序是[y, x] for x, cart_y in pixels: # 转换回OpenCV的y坐标(原点在左上角) y = height - cart_y - 1 modified_image[y, x] = (0, 0, 255) cv.imshow('Modified Image', modified_image) cv.waitKey(0) cv.destroyAllWindows()
关键修正点说明:
- 把图像转为灰度图后再判断亮像素,避免三通道判断的混乱。
- 函数内使用传入图像的
shape,不再依赖全局变量。 - 赋值时使用
modified_image[y, x],符合OpenCV的索引顺序。 - 明确区分OpenCV坐标(y向下)和笛卡尔坐标(y向上)的转换,确保后续项目使用坐标时不会出错。
内容的提问来源于stack exchange,提问作者Jaime Manuel Garcia Dominguez
相关产品推荐
相关产品推荐

