15

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

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

4

5 回答 5

18

您的问题似乎特别是在询问 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中使用了一种称为调色板方法的方法,它比遍历像素非常快。您可以在此处找到更多详细信息如何使用它来加速代码:Numpy 中的快速数组操作

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

原始图像:

在此处输入图像描述

2级:

在此处输入图像描述

4级:

在此处输入图像描述

8级:

在此处输入图像描述

等等...

于 2012-06-17T15:49:18.387 回答
11

我们可以使用 numpy 非常巧妙地做到这一点,而无需担心通道!

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

输出:

在此处输入图像描述

输入:

在此处输入图像描述

于 2012-06-16T16:25:45.097 回答
0

我见过的最酷的“海报化”使用 Mean Shift Segmentation。我使用作者的 GitHub存储库中的代码创建了以下图像(您需要取消注释Maincpp.cpp 的第 27 行才能执行分割步骤)。

在此处输入图像描述

于 2019-10-19T20:00:16.733 回答
0

来自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

输出 n=5

于 2021-10-07T15:24:30.253 回答
0

使用cv::LUT()。这是最简单和最快的方法。

cv::Mat posterize(const cv::Mat &bgrmat, uint8_t lvls)
{
    cv::Mat lookUpTable(1, 256, CV_8U);
    uchar* p = lookUpTable.ptr();
    float step = 255.0f / lvls;
    for(int i = 0; i < 256; ++i)
        p[i] = static_cast<uchar>(step * std::floor(i / step));
    cv::Mat omat;
    cv::LUT(bgrmat,lookUpTable,omat);
    return omat;
}
于 2022-03-03T07:43:04.667 回答