OpenCV (4) --- Разложение и синтез битовой плоскости

OpenCV
OpenCV (4) --- Разложение и синтез битовой плоскости

@TOC

Что такое декомпозиция битовой плоскости

Объединение значений двоичных пикселей в единой битовой позиции в изображении в градациях серого для получения бинарного изображения называется битовой плоскостью изображения в градациях серого, а этот процесс называется декомпозицией битовой плоскости. Например, битовая плоскость «наименее значащий бит» может быть сформирована путем объединения значений младших значащих битов в двоичных битах всех пикселей в изображении в градациях серого.

В 8-битном изображении в градациях серого каждый пиксель представлен 8-битным двоичным кодом, а его значение находится в диапазоне от [0,255] от низкого до высокого соответственно:

00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000

Взяв эти значения, мы можем получить карту декомпозиции всех битовых плоскостей с помощью побитовой операции И. А какая польза? Умные друзья должны знать. Например, если нам нужно добавить водяной знак к изображению, следует ли его добавлять в старшей битовой плоскости или в младшей битовой плоскости?

Конечно, это младшая разрядность, потому что в ней меньше всего информации, и удалить водяной знак после добавления водяного знака проще.

Разложение битовой плоскости в оттенках серого

Теперь, когда мы знаем о декомпозиции битовой плоскости в градациях серого и обо всем, что с ней связано. Далее давайте возьмем изображение чертежа и извлечем все его битовые плоскости.

Конкретный код выглядит следующим образом:

import cv2
import numpy as np

a = cv2.imread("4.jpg", 0)
r, c = a.shape
b = np.zeros((r, c, 8), dtype=np.uint8)
for i in range(8):
    b[:, :, i] = 2 ** i
for i in range(8):
    temp = cv2.bitwise_and(a, b[:, :, i])
    cv2.imshow(str(i),temp)
cv2.waitKey()
cv2.destroyAllWindows()

После запуска мы получаем 8-битные плоскости изображения в градациях серого:

1.pngИсходное изображение такое:

2.png

Разложение битовой плоскости цветовой карты

Поскольку изображения в градациях серого имеют свои битовые плоскости, цветные изображения также могут быть извлечены. Но поскольку матрица цветного изображения представляет собой трехмерную матрицу, нам нужно выполнить побитовую операцию И над каждым значением цвета RGB.

Конкретный код выглядит следующим образом:

import cv2
import numpy as np

a = cv2.imread("4.jpg", -1)
x, y, z = a.shape
b = np.zeros((x, y, 8), dtype=np.uint8)
for i in range(8):
    b[:, :, i] = 2 ** i
temp = np.zeros((x, y, 3), dtype=np.uint8)
for i in range(8):
    temp[:, :, 0] = cv2.bitwise_and(a[:, :, 0], b[:, :, i])
    temp[:, :, 1] = cv2.bitwise_and(a[:, :, 1], b[:, :, i])
    temp[:, :, 2] = cv2.bitwise_and(a[:, :, 2], b[:, :, i])
    cv2.imshow(str(i), temp)
cv2.waitKey()
cv2.destroyAllWindows()

После запуска мы получим следующие 8-битные плоскости:

3.png

порог

Не знаю, заметили читатели, будь то изображение в градациях серого или цветное, детали растрового изображения 0-4 почти невидимы, и все они черные. Как сделать детали более заметными в это время?

Ответ - изменить его пороги.Они должны быть очень маленькими.Напрямую меняем их на 255,и все детали кроме 0 можно подсветить. Теперь давайте изменим код для извлечения растрового изображения цвета, код выглядит следующим образом:

import cv2
import numpy as np

a = cv2.imread("4.jpg", -1)
x, y, z = a.shape
b = np.zeros((x, y, 8), dtype=np.uint8)
for i in range(8):
    b[:, :, i] = 2 ** i
temp = np.zeros((x, y, 3), dtype=np.uint8)
for i in range(8):
    temp[:, :, 0] = cv2.bitwise_and(a[:, :, 0], b[:, :, i])
    temp[:, :, 1] = cv2.bitwise_and(a[:, :, 1], b[:, :, i])
    temp[:, :, 2] = cv2.bitwise_and(a[:, :, 2], b[:, :, i])
    m = temp[:, :] > 0
    temp[m] = 255
    cv2.imshow(str(i), temp)
cv2.waitKey()
cv2.destroyAllWindows()

После запуска эффект следующий:

4.png

Композиция цветовой битовой плоскости

Раз есть разложение, должен быть и синтез. Так что нам также нужно освоить, как объединить все битовые плоскости в одно изображение. код показывает, как показано ниже:

import cv2
import numpy as np

a = cv2.imread("4.jpg", -1)
x, y, z = a.shape
b = np.zeros((x, y, 8), dtype=np.uint8)
for i in range(8):
    b[:, :, i] = 2 ** i
bit_img = np.zeros((x, y, 3), dtype=np.uint8)
temp = np.zeros((x, y, 3), 'uint8')
for i in range(8):
    bit_img[:, :, 0] = cv2.bitwise_and(a[:, :, 0], b[:, :, i])
    bit_img[:, :, 1] = cv2.bitwise_and(a[:, :, 1], b[:, :, i])
    bit_img[:, :, 2] = cv2.bitwise_and(a[:, :, 2], b[:, :, i])

    temp[:, :, 0] = cv2.bitwise_or(temp[:, :, 0], bit_img[:, :, 0])
    temp[:, :, 1] = cv2.bitwise_or(temp[:, :, 1], bit_img[:, :, 1])
    temp[:, :, 2] = cv2.bitwise_or(temp[:, :, 2], bit_img[:, :, 2])

    m = bit_img[:, :] > 0
    bit_img[m] = 255
    #cv2.imshow(str(i)+".bmp",bit_img)
cv2.imshow('00000000', temp)
cv2.waitKey()
cv2.destroyAllWindows()

Здесь мы объединяемся в карту битовой плоскости с помощью функции побитового ИЛИ побитового_или. После запуска temp — исходное изображение, а bit_img — битовая плоскость. Таким образом, когда мы фактически обрабатываем его, мы можем объединить изображение битовой плоскости bit_img в одно изображение после обработки его в середине.

Композитинг в градациях серого

Цвет сложнее, чем оттенки серого, а слияние растровых изображений относительно просто. Без лишних слов перейдем непосредственно к коду:

import cv2
import numpy as np

a = cv2.imread("4.jpg", 0)
r, c = a.shape
b = np.zeros((r, c, 8), dtype=np.uint8)
for i in range(8):
    b[:, :, i] = 2 ** i
c=np.zeros((r,c),dtype=np.uint8)
for i in range(8):
    temp = cv2.bitwise_and(a, b[:, :, i])
    c=cv2.bitwise_or(c,temp)
cv2.imshow("111",c)
cv2.waitKey()
cv2.destroyAllWindows()