【问题标题】:Adobe Photoshop-style posterization and OpenCVAdobe Photoshop 风格的分色和 OpenCV
【发布时间】:2012-06-19 08:05:23
【问题描述】:

Adobe Photoshop 似乎通过根据指定的级别数分别量化每个颜色通道来进行后处理。因此,例如,如果您指定 2 个级别,那么它将采用 R 值,如果您的 R 值小于 128,则将其设置为 0;如果您的值 >= 128,则将其设置为 255。它对 G 和 B 执行相同的操作.

除了遍历每个像素并进行比较并分别设置值之外,是否有一种有效的方法可以在 Python 中使用 OpenCV 执行此操作?由于 OpenCV 2.4 中的图像是 NumPy ndarray,是否有一种有效的方法可以严格通过 NumPy 进行此计算?

【问题讨论】:

标签: python opencv numpy


【解决方案1】:

你的问题似乎是在问关于 2 级的问题。但是超过 2 级的呢?所以我在下面添加了一个代码,它可以对任何颜色级别进行分色。

import numpy as np
import cv2

im = cv2.imread('messi5.jpg')

n = 2    # Number of levels of quantization

indices = np.arange(0,256)   # List of all colors 

divider = np.linspace(0,255,n+1)[1] # we get a divider

quantiz = np.int0(np.linspace(0,255,n)) # we get quantization colors

color_levels = np.clip(np.int0(indices/divider),0,n-1) # color levels 0,1,2..

palette = quantiz[color_levels] # Creating the palette

im2 = palette[im]  # Applying palette on image

im2 = cv2.convertScaleAbs(im2) # Converting image back to uint8

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

这段代码使用了一种称为 Numpy 中的调色板方法 的方法,它比遍历像素非常快。您可以在此处找到更多详细信息如何使用它来加速代码:Fast Array Manipulation in Numpy

以下是我在不同级别得到的结果:

原图:

2级:

4级:

8级:

等等……

【讨论】:

  • 我正在尝试用 c++ 转换它,如何量化颜色
  • 首先你在两个级别之间找到一个数字。例如,如果是 2 个级别,则取 127 来划分颜色。然后所有的颜色变成0和1。如果是3个级别,取85个等等。然后除法将得到 0,1,2。然后将它们扩展为 0,127、255 等。
【解决方案2】:

我们可以使用 numpy 非常巧妙地做到这一点,完全不用担心渠道!

import cv2
im = cv2.imread('1_tree_small.jpg')
im[im >= 128]= 255
im[im < 128] = 0
cv2.imwrite('out.jpg', im)

输出:

输入:

【讨论】:

  • 哇,太棒了,谢谢!我是 numpy 的新手,我没有意识到它是如此强大,我将不得不深入研究它!再次感谢!
  • 如果您想将其用作艺术或风格效果,我强烈建议您先将Gaussian blur 应用于图像,它会清除参差不齐的边缘。您可以在使用较小的内核进行抗锯齿后再次应用模糊。
【解决方案3】:

我见过的最酷的“海报化”用途 Mean Shift Segmentation。我使用了代码 从author's GitHub repo 创建以下图像(您需要 取消注释line 27 of Maincpp.cpp 以执行分段步骤)。

【讨论】:

    【解决方案4】:

    对来自fraxel的答案的n个级别进行泛化

    import cv2 as cv
    import matplotlib.pyplot as plt
    
    im = cv.imread("Lenna.png") 
    
    n = 5
    
    for i in range(n):
        im[(im >= i*255/n) & (im < (i+1)*255/n)] = i*255/(n-1)
    
    plt.imshow(cv.cvtColor(im, cv.COLOR_BGRA2RGB))
    plt.show()
    

    n = 2

    n = 5

    【讨论】:

    • 嗨皮埃尔,欢迎来到StackOverFlow 社区?。感谢您的回答,但最好解释一下为什么您的答案是上述答案的改进版本。最佳。
    • 有一些例子更好
    猜你喜欢
    • 2011-03-13
    • 1970-01-01
    • 1970-01-01
    • 2014-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-13
    相关资源
    最近更新 更多