简体   繁体   English

在 Python 和 OpenCV 中反转图像

[英]inverting image in Python with OpenCV

I want to load a color image, convert it to grayscale, and then invert the data in the file.我想加载彩色图像,将其转换为灰度图像,然后反转文件中的数据。

What I need: to iterate over the array in OpenCV and change every single value with this formula (it might be wrong but it seems reasonable for me):我需要的是:迭代 OpenCV 中的数组并使用此公式更改每个值(这可能是错误的,但对我来说似乎是合理的):

img[x,y] = abs(img[x,y] - 255)

but I don't understand why doesn't it works:但我不明白为什么它不起作用:

def inverte(imagem, name):
    imagem = abs(imagem - 255)
    cv2.imwrite(name, imagem)


def inverte2(imagem, name):
    for x in np.nditer(imagem, op_flags=['readwrite']):
        x = abs(x - 255)
    cv2.imwrite(name, imagem)


if __name__ == '__main__':
    nome = str(sys.argv[1])
    image = cv2.imread(nome)
    gs_imagem = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    inverte(gs_imagem, "invertida.png")
    inverte2(gs_imagem, "invertida2.png")

I don't want to do an explicit loop (I am trying to be more pythonic).我不想做一个显式循环(我想变得更像 pythonic)。 I can see that in one image that got a white background it turned black, but only this it doesn't looks like the other colors are having much (if any) change.我可以看到在一张白色背景的图像中它变成了黑色,但只有这一点看起来不像其他 colors 有太多(如果有的话)变化。

You almost did it.你几乎做到了。 You were tricked by the fact that abs(imagem-255) will give a wrong result since your dtype is an unsigned integer.您被abs(imagem-255)会给出错误结果的事实所欺骗,因为您的dtype是无符号整数。 You have to do (255-imagem) in order to keep the integers unsigned:你必须做(255-imagem)以保持整数无符号:

def inverte(imagem, name):
    imagem = (255-imagem)
    cv2.imwrite(name, imagem)

You can also invert the image using the bitwise_not function of OpenCV:您还可以使用 OpenCV 的bitwise_not函数反转图像:

imagem = cv2.bitwise_not(imagem)

Alternatively, you could invert the image using the bitwise_not function of OpenCV:或者,您可以使用 OpenCV 的bitwise_not函数反转图像:

imagem = cv2.bitwise_not(imagem)

I liked this example.我喜欢这个例子。

You can use "tilde" operator to do it:您可以使用“波浪号”运算符来执行此操作:

import cv2
image = cv2.imread("img.png")
image = ~image
cv2.imwrite("img_inv.png",image)

This is because the "tilde" operator (also known as unary operator) works doing a complement dependent on the type of object这是因为“波浪号”运算符(也称为一元运算符)根据对象的类型进行补码

for example for integers, its formula is:例如对于整数,它的公式是:

x + (~x) = -1 x + (~x) = -1

but in this case, opencv use an "uint8 numpy array object" for its images so its range is from 0 to 255但在这种情况下,opencv 对其图像使用“uint8 numpy 数组对象”,因此其范围是从 0 到 255

so if we apply this operator to an "uint8 numpy array object" like this:因此,如果我们将此运算符应用于“uint8 numpy 数组对象”,如下所示:

import numpy as np
x1 = np.array([25,255,10], np.uint8) #for example
x2 = ~x1
print (x2)

we will have as a result:结果是:

[230 0 245]

because its formula is:因为它的公式是:

x2 = 255 - x1 x2 = 255 - x1

and that is exactly what we want to do to solve the problem.这正是我们想要解决的问题。

You can also do it with numpy.你也可以用 numpy 来做。

import cv2
import numpy as np

image = cv2.imread('your_image', 0)
inverted = np.invert(image)

cv2.imwrite('inverted.jpg', inverted)

在 Python/OpenCV 中,我认为你想要:

img = cv2.absDiff(img, 255)

Why not use the first line in the question with numpy ?为什么不将问题的第一行numpy一起使用?

inverted = np.abs(image - 255)

Just as simple as that.就这么简单。 No iteration or any other function needed.无需迭代或任何其他功能。 numpy does that automatically for us :) numpy会自动为我们做到这一点:)

    def invert(self, image=None):
        if image is None:
            image = self.image

        image = image.astype("uint8") # --> pay attention to the image type
        inverted = np.invert(image)
        (thresh, im_bw) = cv2.threshold(inverted, 0, 1, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
        return im_bw

A, This script search pink skin pixel in the image. A、此脚本搜索图像中的粉红色皮肤像素。

It create a mask.它创建一个面具。

It set pink pixel to white and not pink pixels to black它将粉红色像素设置为白色,而不是将粉红色像素设置为黑色

B, Observe the 2 conditions mask>0 and mask==0 B、观察2个条件mask>0和mask==0

import cv2
import numpy as np

# specify desired bgr for mask
desired_color_brg1 = (0,0, 0) #black
desired_color_brg2 = (255,255, 255) #white




# read image in bgr and convert to hsv
path_main_image="../data/person.png"
main_img = cv2.imread(path_main_image)
main_img_hsv=cv2.cvtColor(main_img,cv2.COLOR_BGR2HSV)



# Define lower and uppper limits of what we call "pink skin color"
pink_low=np.array([0,10,60])
pink_hig=np.array([20,150,255])


#create mask
mask=cv2.inRange(main_img_hsv,pink_low,pink_hig)


# Change image to white where we found pink skin
main_img[mask>0]=desired_color_brg1
cv2.imwrite("../data/result1.png",main_img)


# Change image toblack where we NOT found pink skin
main_img[mask==0]=desired_color_brg2
cv2.imwrite("../data/result2.png",main_img)





声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM