解决利用 opencv 调亮图片时,颜色改变问题

问题复现

今天写代码时,需要将图片的亮度进行调整,我是直接在读出来的 R、G、B三个通道上分别增加了一个固定的值。由于颜色值是在[0, 255]区间内的,正常来讲,即使超出了这个范围,利用 opencv 进行展示之前的合并中,也是会自动截断的。但是还是出现了颜色改变的问题。代码如下:

调整亮度的函数:

def imgeAdjustmentLightness(img) :
    B, G, R = cv2.split(img)
    b = copy.deepcopy(B)
    g = copy.deepcopy(G)
    r = copy.deepcopy(R)
    for row in range(len(b)) :
        for col in range(len(b[row])) :
            b[row][col] = b[row][col] + 20
            g[row][col] = g[row][col] + 20
            r[row][col] = r[row][col] + 20
    merged = cv2.merge([b, g, r])
    cv2.imshow("after adjust lightness", merged)

主函数:

# -*- coding: UTF-8 -*-
import numpy as np
import cv2
import copy

# 读取图片信息
img = cv2.imread("01.bmp")
cv2.imshow("origin image", img)
imgeAdjustmentLightness(img)
cv2.waitKey(0)

改变之前的原图:

原图

调整亮度,改变之后的图片:

调整亮度之后

可以看到,很多原来白色的地方都已经变了颜色,一猜就知道,肯定是溢出的问题,但是,为什么会发生溢出呢?为什么没有自动截断呢?

原因

原因其实很简单,因为在调整亮度,加一个特定值的时候,由于通道里的数据类型已经是 np.int8 了,也就是说只有一个子节,最大的存储值也只是 255, 当发生溢出的时候,直接从 0 开始了。。。

也就是说,还没等我们对其进行截断呢,它自己就已经限制住存储范围了。

解决方法

找到问题的原因了,解决发法也比较简单,直接在改变之前进行亮度调整就可以了。

更改调整亮度的函数为:

def imgeAdjustmentLightness(img) :
    B, G, R = cv2.split(img)
    b = copy.deepcopy(B)
    g = copy.deepcopy(G)
    r = copy.deepcopy(R)
    for row in range(len(b)) :
        for col in range(len(b[row])) :
            if b[row][col] > 235 :
                b[row][col] = 255
            else :
                b[row][col] = b[row][col] + 20
            if g[row][col] > 235 :
                g[row][col] = 255
            else :
                g[row][col] = g[row][col] + 20
            if r[row][col] > 235 :
                r[row][col] = 255
            else :
                r[row][col] = r[row][col] + 20
    merged = cv2.merge([b, g, r])
    cv2.imshow("after adjust lightness", merged)

改变之后的效果:

图像亮度调整

其实,就是在增加亮度之前就先判断一波。如果是调低亮度,也是一样的,可以在调低之前,先判断是否能够减去那个亮度的变化值,以防溢出。

调整亮度也可以直接使用 HLS 这个颜色空间,L 就代表了亮度,改变它的效果与 RGB 单通道增加特定值是一样的。但是,溢出的问题就没有这么容易解决了。所以,改变亮度的话,还是 RGB 比较方便一点。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一个简单的示例代码,它使用OpenCV和C语言进行绘制直线和改变直线颜色的操作。 //导入OpenCV库 #include <opencv/cv.h> #include <opencv/highgui.h> int main() { //加载图像 IplImage* img = cvLoadImage("test.jpg", CV_LOAD_IMAGE_COLOR); //定义直线的起点和终点 CvPoint pt1 = cvPoint(10, 10); CvPoint pt2 = cvPoint(50, 50); //定义直线的颜色 CvScalar color = CV_RGB(255, 0, 0); //绘制直线 cvLine(img, pt1, pt2, color, 1, CV_AA, 0); //定义需要改变颜色的区域 CvRect region = cvRect(10, 10, 40, 40); //定义新的颜色 CvScalar new_color = CV_RGB(0, 255, 0); //循环遍历指定区域,改变颜色 for (int i = region.y; i < region.y + region.height; i++) { for (int j = region.x; j < region.x + region.width; j++) { CvScalar pixel = cvGet2D(img, i, j); if (pixel.val[0] == color.val[0] && pixel.val[1] == color.val[1] && pixel.val[2] == color.val[2]) { cvSet2D(img, i, j, new_color); } } } //显示图像 cvNamedWindow("Image", CV_WINDOW_AUTOSIZE); cvShowImage("Image", img); //等待按键 cvWaitKey(0); //释放内存 cvDestroyAllWindows(); return 0; } 在这个示例中,我们首先使用cvLoadImage函数加载一个名为test.jpg的图像。然后,我们定义了直线的起点和终点及其颜色,并使用cvLine函数在图像中绘制直线。 接下来,我们定义了需要更改颜色的区域,并在双重循环中遍历该区域。对于每个像素,我们使用cvGet2D函数获取其值,并检查其是否与直线颜色匹配。如果是这样,则使用cvSet2D函数将其颜色更改为新颜色。 最后,我们使用cvNamedWindow和cvShowImage函数显示更改后的图像,并使用cvWaitKey函数等待按键。当用户按下任何键,我们使用cvDestroyAllWindows函数释放内存。 请注意,此示例仅仅是一个基本的例子,你可以根据你的实际需求来修改代码。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值