Я пытаюсь сделать все белые пиксели на этом изображении красными, но когда я запускаю программу, форма в порядке, но красные пиксели поворачиваются на 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(). Я читал информационную страницу функции, но до сих пор не понимаю, почему это происходит.
Если вы хотите повторить, вот изображение, которое я использую:






Измените эту строку на:
# image[loc_x,loc_y] = (0,0,255)
image[loc_y,loc_x] = (0,0,255)
вместе с
# cartesian_y=height-indices[0]-1
cartesian_y=indices[0]
Вам нужно знать, что массивы numpy и OpenCV — это массивы y, x, тогда как другие пакеты обработки изображений работают по принципу x, y.
Вот результат запуска фиксированного кода:
Как упоминалось в комментарии aRTy
В этой строке вы фактически переворачиваете координату Y сверху вниз:
cartesian_y=height-indices[0]-1. Если вы конвертируете ориентацию OpenCV/numpy (где y=0 — верх) в ориентацию matplotlib (где y=0 — низ), то вам нужно сделать это, когда вы дойдете до раздела matplotlib, а не раньше.
Требуемый эффект получения порогового изображения, которое, по-видимому, является изображением в оттенках серого, также может быть достигнут с использованием упрощенного кода, разделяющего каналы и запускающего порог OpenCV на одном из них:
import cv2 as cv, numpy as np
threshold = 40
image = cv.imread("srcImage.jpg")
_, G, _ = cv.split(image)
_, thresh = cv.threshold(G, threshold, 255, cv.THRESH_BINARY)
black=np.zeros_like(thresh)
red_image = cv.merge([black, black, thresh])
cv.imshow('White areas in source Image marked red', red_image)
cv.waitKey(0)
cv.destroyAllWindows()
Результат будет таким же, даже если два канала будут исключены из рассмотрения.
Вы фактически меняете координату Y в этой строке: cartesian_y=height-indices[0]-1. Вы пытаетесь преобразовать ориентацию numpy (y=0 вверху) в ориентацию matplotlib (y=0 внизу)? Если да, то сделайте это, когда доберетесь до раздела matplotlib, а не раньше.
@aRTy ты.... ты.... Хотел бы я поблагодарить тебя лично XD. Вы совершенно правы.
В коде есть два места, которые пошли не так... см. обновленный ответ для обоих исправленных.
Подумайте об этом. Вы знаете, что белый — это rgb(255,255,255), то же самое, что #fff, когда вы используете шестнадцатеричные цвета в HTML/CSS. Вы хотите превратить белый цвет в красный, т. е. rgb(255,0,0), поэтому вам нужно обнулить зеленый и синий каналы:
import cv2 as cv
# Load image
im = cv.imread('ZXo3LfmS.jpg')
# Zero the blue channel, then the green channel
im[..., 0] = 0
im[..., 1] = 0
# Save result
cv.imwrite('result.png')
Фактически вы можете обнулить синий и зеленый цвета за один раз, выполнив:
im[..., [0,1]] = 0
Обратите внимание, что многоточие (...) означает «все остальные измерения, которые я не удосужился перечислить». Если бы мне по какой-то причине захотелось их перечислить, я мог бы использовать:
im[:, :, 0] = 0 # zero the blue channel
im[:, :, 1] = 0 # zero the green channel
Если вы используете циклы
forдля массивов Numpy, вы, вероятно, ошиблись. Почитайте здесь stackoverflow.com/a/60019059/2836621