Jak mogę szybko zmienić jasność obrazu za pomocą Python + OpenCV?


Mam sekwencję obrazów. Muszę uśrednić jasność tych obrazów.

Pierwszy przykład

(bardzo wolno):
img = cv2.imread('test.jpg') #load rgb image
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) #convert it to hsvfor x in range(0, len(hsv)):
for y in range(0, len(hsv[0])):
hsv[x, y][2] += valueimg = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
cv2.imwrite("image_processed.jpg", img)


Drugi przykład

(szybki)
hsv += value

Ten przykład jest bardzo szybki, ale zmienia wszystkie wartości HSV (potrzebuję tylko zmienić V (jasność))
Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Wiem, że to pytanie jest trochę nieaktualne, ale pomyślałem, że mógłbym opublikować kompletne rozwiązanie, które zadziałało dla mnie (rozwiązuje sytuację przepełnienia, nasycając na 255):
def increase_brightness(img, value=30):
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(hsv) lim = 255 - value
v[v > lim] = 255
v[v <= lim] += value final_hsv = cv2.merge((h, s, v))
img = cv2.cvtColor(final_hsv, cv2.COLOR_HSV2BGR)
return img

Można go używać w następujący sposób:
frame = increase_brightness(frame, value=20)
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Slice
http://docs.scipy.org/doc/nump ... exing
aby wybrać tylko trzeci kanał, a następnie zmienić te elementy -
hsv[:,:,2] += value
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Inne odpowiedzi sugerują wykonanie nasycenia „ręcznie” przy użyciu wszelkiego rodzaju odrętwiającej magii, ale możesz też użyć

cv2.add()
https://docs.opencv.org/3.4.1/ ... fdbd6
i pozwól OpenCV zająć się tym za Ciebie:
import cv2
import numpy as npimage = cv2.read('image.png')
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
value = 42 #whatever value you want to add
cv2.add(hsv[:,:,2], value, hsv[:,:,2])
image = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
cv2.imwrite('out.png', image)
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Iterowanie całego obrazu w celu wprowadzenia zmian nie jest bardzo skalowalną opcją w opencv, Opencv zapewnia wiele metod i funkcji do wykonywania operacji arytmetycznych na danym obrazie.
Możesz po prostu podzielić przekonwertowany obraz HSV na oddzielne kanały, a następnie odpowiednio przetworzyć kanał V:
img = cv2.imread('test.jpg') #load rgb image
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) #convert it to hsvh, s, v = cv2.split(hsv)
v += 255
final_hsv = cv2.merge((h, s, v))img = cv2.cvtColor(final_hsv, cv2.COLOR_HSV2BGR)
cv2.imwrite("image_processed.jpg", img)
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

def change_brightness(img, alpha, beta):
return cv2.addWeighted(img, alpha, np.zeros(img.shape, img.dtype),0, beta)

Oto alfa beta & amp; są parametrami wejściowymi. Każdy piksel w obrazie wejściowym zmieni się zgodnie z tym wzorem.
alpha(pixel_value) + beta.

Niższa wartość alfa wynosząca 2 lub 3 jest dobra
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

import cv2
import numpy as npimage = cv2.imread('image.jpg')
image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)v = image[:, :, 2]
v = np.where(v <= 255 - increase, v + increase, 255)
image[:, :, 2] = vimage = cv2.cvtColor(image, cv2.COLOR_HSV2BGR)cv2.imshow('Brightness', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Mam nadzieję, że to komuś się przyda
@ Odpowiedź Divakara

Python, OpenCV: zwiększ jasność obrazu bez przepełnienia tablicy UINT8
https://coderoad.ru/37822375/
mImage = cv2.imread('image1.jpg')hsvImg = cv2.cvtColor(mImage,cv2.COLOR_BGR2HSV)value = 0vValue = hsvImg[...,2]
hsvImg[...,2] = np.where((255-vValue)<value,255,vValue+value)plt.subplot(111), plt.imshow(cv2.cvtColor(hsvImg,cv2.COLOR_HSV2RGB))
plt.title('brightened image'), plt.xticks([]), plt.yticks([])
plt.show()

Aby zmniejszyć jasność
mImage = cv2.imread('image1.jpg')hsvImg = cv2.cvtColor(mImage,cv2.COLOR_BGR2HSV)# decreasing the V channel by a factor from the original
hsvImg[...,2] = hsvImg[...,2]*0.6plt.subplot(111), plt.imshow(cv2.cvtColor(hsvImg,cv2.COLOR_HSV2RGB))
plt.title('brightened image'), plt.xticks([]), plt.yticks([])
plt.show()
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

To było moje rozwiązanie, aby zarówno zwiększyć, jak i zmniejszyć jasność. Miałem problemy z kilkoma innymi odpowiedziami. Funkcja przyjmuje wartość dodatnią lub ujemną i zmienia jasność.
przykład w kodzie
img = cv2.imread(path_to_image)
img = change_brightness(img, value=30) #increases
img = change_brightness(img, value=-30) #decreases

nazywana funkcją
def change_brightness(img, value=30):
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(hsv)
v = cv2.add(v,value)
v[v > 255] = 255
v[v < 0] = 0
final_hsv = cv2.merge((h, s, v))
img = cv2.cvtColor(final_hsv, cv2.COLOR_HSV2BGR)
return img
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Możesz użyć tej funkcji, aby zmienić żądane

jasność lub kontrast przy użyciu C ++
https://www.life2coding.com/br ... cv-c/
tak jak robisz to w Photoshopie lub innym podobnym programie do edycji zdjęć.
def apply_brightness_contrast(input_img, brightness = 255, contrast = 127):
brightness = map(brightness, 0, 510, -255, 255)
contrast = map(contrast, 0, 254, -127, 127) if brightness != 0:
if brightness > 0:
shadow = brightness
highlight = 255
else:
shadow = 0
highlight = 255 + brightness
alpha_b = (highlight - shadow)/255
gamma_b = shadow buf = cv2.addWeighted(input_img, alpha_b, input_img, 0, gamma_b)
else:
buf = input_img.copy() if contrast != 0:
f = float(131 * (contrast + 127))/(127 * (131 - contrast))
alpha_c = f
gamma_c = 127*(1-f) buf = cv2.addWeighted(buf, alpha_c, buf, 0, gamma_c) cv2.putText(buf,'B:{},C:{}'.format(brightness,contrast),(10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
return bufdef map(x, in_min, in_max, out_min, out_max):
return int((x-in_min) * (out_max-out_min)/(in_max-in_min) + out_min)

Następnie musisz wywołać funkcje, tworząc pasek śledzenia za pomocą
cv2.createTrackbar ()
, a także wywołać powyższe funkcje z odpowiednimi parametrami. Funkcja
map ()
może służyć do wyświetlania wartości luminancji w zakresie od -255 do +255 i wartości kontrastu od -127 do +127. Możesz sprawdzić pełne informacje o

o implementacjach Pythona tutaj
https://www.life2coding.com/ch ... thon/
.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Wiem, że dostosowanie jasności obrazu nie musi być takie trudne. Poza tym jest już wiele świetnych odpowiedzi. Chciałbym poprawić odpowiedź @ BillGrates, aby działała na obrazach w skali szarości i ze zmniejszoną jasnością:
value = -255
tworzy czarny obraz, a
value = 255
tworzy biały ...
<pre class="lang-py prettyprint-override">
def adjust_brightness(img, value):
num_channels = 1 if len(img.shape) < 3 else 1 if img.shape[-1] == 1 else 3
img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) if num_channels == 1 else img
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(hsv) if value >= 0:
lim = 255 - value
v[v > lim] = 255
v[v <= lim] += value
else:
value = int(-value)
lim = 0 + value
v[v < lim] = 0
v[v >= lim] -= value final_hsv = cv2.merge((h, s, v)) img = cv2.cvtColor(final_hsv, cv2.COLOR_HSV2BGR)
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) if num_channels == 1 else img
return img
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Kanały HSV są typu uint8, a zakres odcieni to [0, 179]. Dlatego po dodaniu dużej liczby lub liczby ujemnej Python zwraca niepotrzebny wynik. Więc w kanale hue musimy zmienić na int16, a następnie z powrotem na uint8. Kanały nasycenia (S) i wartości (V) mają ten sam problem, więc musimy sprawdzić wartość przed dodaniem lub odjęciem.
Oto moje rozwiązanie do losowej zmiany odcienia, nasycenia i wartości. Opiera się na przykładowym kodzie

@alkasm
https://stackoverflow.com/a/49697944/10151497
i

@bill-grates
https://stackoverflow.com/a/47427398/10151497
.
def shift_channel(c, amount):
if amount > 0:
lim = 255 - amount
c[c >= lim] = 255
c[c < lim] += amount
elif amount < 0:
amount = -amount
lim = amount
c[c <= lim] = 0
c[c > lim] -= amount
return crand_h, rand_s, rand_v = 50, 50, 50
img_hsv = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(img_hsv)
# Random shift hue
shift_h = random.randint(-rand_h, rand_h)
h = ((h.astype('int16') + shift_h) % 180).astype('uint8')
# Random shift saturation
shift_s = random.randint(-rand_s, rand_s)
s = shift_channel(s, shift_s)
# Random shift value
shift_v = random.randint(-rand_v, rand_v)
v = shift_channel(v, shift_v)
shift_hsv = cv2.merge([h, s, v])
print(shift_h, shift_s, shift_v)
img_rgb = cv2.cvtColor(shift_hsv, cv2.COLOR_HSV2RGB)
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Może jestem za stary, ale używam cv.covertTo, który działa dla mnie
Mat resultBrightImage; 
origImage.convertTo(resultBrightImage, -1, 1, percent);// Where percent = (int)(percent_val/100)*255, e.g., percent = 50 to increase brightness by 50%

ConvertTo używa saturate_cast na końcu, aby uniknąć przepełnienia. Nie używam Pythona i to jest powyżej w C ++, ale mam nadzieję, że łatwo konwertuje do Pythona i mam nadzieję, że to pomoże

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się