Ответ 1
Slice
, чтобы выбрать только третий канал, а затем изменить эти элементы -
hsv[:,:,2] += value
У меня есть последовательность изображений. Мне нужно усреднить яркость этих изображений.
Первый пример (очень медленно):
img = cv2.imread('test.jpg') #load rgb image
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) #convert it to hsv
for x in range(0, len(hsv)):
for y in range(0, len(hsv[0])):
hsv[x, y][2] += value
img = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
cv2.imwrite("image_processed.jpg", img)
Второй пример (быстро)
hsv += value
Этот пример очень быстрый, но он изменяет все значения HSV (мне нужно изменить только V (яркость))
Slice
, чтобы выбрать только третий канал, а затем изменить эти элементы -
hsv[:,:,2] += value
Я знаю, что этот вопрос немного стар, но я думал, что могу опубликовать полное решение, которое сработало для меня (заботится о ситуации переполнения, насыщаясь 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
Это можно использовать следующим образом:
frame = increase_brightness(frame, value=20)
В других ответах предлагается выполнять насыщение "вручную", используя всевозможную магию, но вы также можете использовать cv2.add() и позволить OpenCV справиться с этим для вас:
import cv2
import numpy as np
image = 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)
Итерация по всему изображению для внесения изменений не является очень масштабируемой опцией в opencv, Opencv предоставляет множество методов и функций для выполнения арифметических операций на данном изображении.
Вы можете просто разбить преобразованное изображение HSV в отдельных каналах, а затем обработать V-канал соответственно следующим образом:
img = cv2.imread('test.jpg') #load rgb image
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) #convert it to hsv
h, 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)
import cv2
import numpy as np
image = cv2.imread('image.jpg')
image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
increase = 100
v = image[:, :, 2]
v = np.where(v <= 255 - increase, v + increase, 255)
image[:, :, 2] = v
image = cv2.cvtColor(image, cv2.COLOR_HSV2BGR)
cv2.imshow('Brightness', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
Надеюсь, это кому-нибудь пригодится
@Divakar answer Python, OpenCV: увеличение яркости изображения без переполнения массива UINT8
mImage = cv2.imread('image1.jpg')
hsvImg = cv2.cvtColor(mImage,cv2.COLOR_BGR2HSV)
value = 0
vValue = 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()
Уменьшить яркость
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.6
plt.subplot(111), plt.imshow(cv2.cvtColor(hsvImg,cv2.COLOR_HSV2RGB))
plt.title('brightened image'), plt.xticks([]), plt.yticks([])
plt.show()
def change_brightness(img, alpha, beta):
return cv2.addWeighted(img, alpha, np.zeros(img.shape, img.dtype),0, beta)
Здесь альфа и бета - входные параметры. Каждый пиксель входного изображения будет меняться в соответствии с этой формулой.
alpha(pixel_value) + beta.
Хорошее значение альфа, например, 2 или 3
Может быть, слишком стар, но я использую cv.covertTo, который работает для меня
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 использует saturate_cast в конце, чтобы избежать переполнения. Я не использую Python, а вышеперечисленное есть в C++, но я надеюсь, что он легко конвертируется в Python, и надеюсь, что это поможет
Вы можете использовать эту функцию, чтобы изменить желаемую яркость или контрастность, используя C++ так же, как вы делаете это в фотошопе или другом подобном программном обеспечении для редактирования фотографий.
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 buf
def 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)
После этого вам нужно вызвать функции, создав трекбар с помощью cv2.createTrackbar()
и вызвать вышеупомянутые функции с соответствующими параметрами. Чтобы отобразить значения яркости в диапазоне от -255 до +255 и значения контрастности -127 до +127, вы можете использовать эту функцию map()
. Вы можете проверить полную информацию о реализации Python здесь.
Я знаю, что это не должно быть так сложно и там настроить яркость изображения. Кроме того, уже есть много хороших ответов. Я хотел бы улучшить ответ @BillGrates, чтобы он работал на изображениях в градациях серого и при уменьшении яркости: value = -255
создает черное изображение, а value = 255
- белое.
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