I am trying to turn all of the white pixels in this image red, but when I run the program the shape is fine but the red pixels are rotated 90 degrees:
This is the current code that I am using to do this:
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()
I do need the location of the white points as I will use them later for the second part of the project. I suspect the problem has something to do with the np.column_stack(). I have been reading the info page of the function but I still do not understand why this happens.
If you want to replicate here is also the image that I am using:
Change this line to:
# image[loc_x,loc_y] = (0,0,255)
image[loc_y,loc_x] = (0,0,255)
along with
# cartesian_y=height-indices[0]-1
cartesian_y=indices[0]
You need to know that numpy and OpenCV arrays are y,x ones, where other image processing packages work the x,y way.
Here the result of running the fixed code:
As mentioned in a comment by aRTy
You are effectively flipping the y-coordinate top-down in this line:
cartesian_y=height-indices[0]-1
. If you are converting from OpenCV/numpy orientation (where y=0 is top) to matplotlib orientation (where y=0 is bottom) then you need to do that when you reach the matplotlib section, not before.
The required effect of getting the thresholded image which is apparently a grayscale one can also be achieved using simplified code separating the channels and running OpenCV threshold on one of them:
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()
The result appears to be the same even if two channels are skipped from consideration.