Python Opencv - 无法更改图片的像素值

时间:2017-08-10 12:18:25

标签: python opencv pixel

需要将白色像素更改为下面给出的图片的黑色和黑色像素为白色 enter image description here

    import cv2

    img=cv2.imread("cvlogo.png")

带有白色背景的基本opencv徽标,并将图片调整为固定的已知尺寸

    img=cv2.resize(img, (300,300))#(width,height)


    row,col=0,0
    i=0

现在使用for循环

按行和列位置检查每个像素

如果像素为白色,则将其更改为黑色,或者如果像素为黑色,则将其更改为白色。

    for row in range(0,300,1):
        print(row)
        for col in range(0,300,1):
            print(col)
            if img[row,col] is [255,255,255] : #I have used == instead of 'is'..but there is no change 
                img[row,col]=[0,0,0]
            elif img[row,col] is [0,0,0]:
                img[row,col]=[255,255,255]

执行中没有错误,但它没有分别将像素值更改为黑色或白色。更多if if语句也没有执行..太多混乱..

    cv2.imshow('img',img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

3 个答案:

答案 0 :(得分:2)

我认为这应该有效。 :) (我使用numpy来获取宽度和高度值 - 你不需要这个)

import cv2

img=cv2.imread("cvlogo.png")
img=cv2.resize(img, (300,300))
height, width, channels = img.shape

white = [255,255,255]
black = [0,0,0]

for x in range(0,width):
    for y in range(0,height):
        channels_xy = img[y,x]
        if all(channels_xy == white):    
            img[y,x] = black

        elif all(channels_xy == black):
            img[y,x] = white

cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()

答案 1 :(得分:1)

我不太有经验,但是我会使用numpy.where()来做,这比循环要快。

_socket.gethostbyname

enter image description here

答案 2 :(得分:0)

有点晚了,但是我想为解决这种情况提供另一种方法。我的方法基于图像索引,它比遍历图像作为接受答案中使用的方法要快。

我对这两个代码进行了一些时间测量,以说明我刚才所说的内容。看看下面的代码:

import cv2
from matplotlib import pyplot as plt

# Reading image to be used in the montage, this step is not important
original = cv2.imread('imgs/opencv.png')

# Starting time measurement
e1 = cv2.getTickCount()

# Reading the image
img = cv2.imread('imgs/opencv.png')

# Converting the image to grayscale
imgGray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

# Converting the grayscale image into a binary image to get the whole image
ret,imgBinAll = cv2.threshold(imgGray,175,255,cv2.THRESH_BINARY)

# Converting the grayscale image into a binary image to get the text
ret,imgBinText = cv2.threshold(imgGray,5,255,cv2.THRESH_BINARY)

# Changing white pixels from original image to black
img[imgBinAll == 255] = [0,0,0]

# Changing black pixels from original image to white
img[imgBinText == 0] = [255,255,255]

# Finishing time measurement
e2 = cv2.getTickCount()
t = (e2 - e1)/cv2.getTickFrequency()
print(f'Time spent in seconds: {t}')

这时我停止计时,因为下一步只是绘制蒙太奇,代码如下:

# Plotting the image
plt.subplot(1,5,1),plt.imshow(original)
plt.title('original')
plt.xticks([]),plt.yticks([])
plt.subplot(1,5,2),plt.imshow(imgGray,'gray')
plt.title('grayscale')
plt.xticks([]),plt.yticks([])
plt.subplot(1,5,3),plt.imshow(imgBinAll,'gray')
plt.title('binary - all')
plt.xticks([]),plt.yticks([])
plt.subplot(1,5,4),plt.imshow(imgBinText,'gray')
plt.title('binary - text')
plt.xticks([]),plt.yticks([])
plt.subplot(1,5,5),plt.imshow(img,'gray')
plt.title('final result')
plt.xticks([]),plt.yticks([])
plt.show()

那是最终结果:

Montage showing all steps of the proposed approach

这是消耗的时间(打印在控制台中):

Time spent in seconds: 0.008526025

为了比较这两种方法,我对调整图像大小的行进行了注释。另外,我在imshow命令之前停止了计时。这些是结果:

Time spent in seconds: 1.837972522

Final result of the looping approach

如果同时查看两个图像,您将看到一些轮廓差异。有时,当您进行图像处理时,效率是关键。因此,最好在可能的地方节省时间。这种方法可以适应不同的情况,请查看threshold documentation