GVKun编程网logo

如何使用Python + OpenCV的快速变化的图像亮度?(python opencv调整图片亮度)

8

对于想了解如何使用Python+OpenCV的快速变化的图像亮度?的读者,本文将提供新的信息,我们将详细介绍pythonopencv调整图片亮度,并且为您提供关于OpenCVPython:3通道flo

对于想了解如何使用Python + OpenCV的快速变化的图像亮度?的读者,本文将提供新的信息,我们将详细介绍python opencv调整图片亮度,并且为您提供关于OpenCV Python:3通道float32图像读取的快速解决方案?、Opencv 图像亮度调节的几种方式、OpenCV(C++/Python)中的图像对齐(ECC)、opencv::调整图像亮度与对比度的有价值信息。

本文目录一览:

如何使用Python + OpenCV的快速变化的图像亮度?(python opencv调整图片亮度)

如何使用Python + OpenCV的快速变化的图像亮度?(python opencv调整图片亮度)

我有图像序列。我需要这些图像的平均亮度。

第一个例子 (很慢):

img = cv2.imread(''test.jpg'') #load rgb imagehsv = 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)

第二个例子 (快)

hsv += value

这个例子非常快,但它改变了所有值HSV(我只需要更改V(亮度))

答案1

小编典典

Slice 只选择第三通道,然后修改这些元素 -

hsv[:,:,2] += value

OpenCV Python:3通道float32图像读取的快速解决方案?

OpenCV Python:3通道float32图像读取的快速解决方案?

我需要类型为3通道RBG排序的彩色图像,float32其值在[0.0,1.0]每个彩色通道的间隔中。

这是我目前的解决方案:

def read_images(imagelist):
    buffer = list()
    for f in imagelist:
        # load single image,convert to float32
        img = cv2.imread(f).astype(np.float32)
        # change interval from [0,255] to [0.0,1.0]
        img /= 255.0
        # leave out alpha channel,if any
        if img.shape[2] == 4:
           img = img[:,:,0:3]
        buffer.append(img)
    return np.array(buffer)

此后,在图像处理程序中,我改变BGR到RGB排序(因为cv2imread默认读取BGR顺序图像)。

对于大型图像集,此过程非常耗时:我正在加载数千张图像进行预处理,然后将图像提供给TensorFlow中实现的某些神经网络。

有没有办法改善这种方法的性能?

Opencv 图像亮度调节的几种方式

Opencv 图像亮度调节的几种方式

《QT 插件化图像算法研究平台》提供了多种亮度调节方式。

1、仿 Photoshop,RGB 曲线调整。4 个通道 RGB、R、G、B,依次调整亮度、红、绿、蓝。

RGB曲线调整

相关源代码、原理,请参见:OpenCV 实现 Photoshop 曲线调整

2、仿 Photoshop,HSV 曲线调整。3 个通道 Hue、Saturation、Value,依次调整色调、饱和度、亮度。

相关源代码、原理,请参见:OpenCV 实现 Photoshop 曲线调整

3、bright,直接系数相乘,直接系数相加

乘数大于 1,可提高亮度与对比度。乘数小于 1,可降低亮度与对比度。

加数大于 0,可提高亮度。加数小于 0,可降低亮度。

参考代码:

void bright(Mat &input,Mat &output,Mat &,string arg)
{
    auto selectRect= processWinGetSelectionRect();//获取选择区域,可只对区域内图像亮度调节
    selectRect=roiFormat(input,selectRect);
    vector<string> argVec;
    splitArg(arg,argVec);
    auto coeff=atof(argVec[0].c_str());
    auto val=atof(argVec[1].c_str());

    if(selectRect.width >0)
    {
        output = input(selectRect);//roi
    }
    else
        output = input;
    //有可能是roi
    output=output*coeff+Scalar(val,val,val);
    output = input;
}

4、gamma

gamma 值小于 1 时,整体亮度提升,低灰度处的对比度增加。

gamma 值大于 1 时,整体亮度减小,高灰度处的对比度增加。

参考代码:

void gamma(Mat &input,Mat &output,Mat &,string arg)
{
 
 
    auto selectRect= processWinGetSelectionRect();
    selectRect=roiFormat(input,selectRect);

    double gamma=atof(arg.c_str());
    unsigned char lut[256];
    for(int i=0;i < 256;i++)
    {
        lut[i] = saturate_cast<uchar>(pow((float)i/255.0,gamma) * 255.0f);
    }
    if(selectRect.width >0)
    {
        output = input(selectRect);
    }
    else
        output = input;
    int channels = input.channels();
    switch(channels)
    {
    case 1:
    {
        MatIterator_<uchar> it = output.begin<uchar>();
        MatIterator_<uchar> end = output.end<uchar>();
        while(it != end)
        {
            *it = lut[(*it)];
            it ++;
        }
        break;
    }
    case 3:
    {
        MatIterator_<Vec3b> it = output.begin<Vec3b>();
        MatIterator_<Vec3b> end = output.end<Vec3b>();
        while(it != end)
        {
            (*it)[0] = lut[(*it)[0]];
            (*it)[1] = lut[(*it)[1]];
            (*it)[2] = lut[(*it)[2]];
            it ++;
        }
        break;
    }
    default:
        break;
    }
    output=input;
}

5、log

对数变换:扩展图像中的暗像素值,压缩高灰度值。

参考代码:

void log(Mat &input,Mat &output,Mat &,string)
{

     //Log对数图像增强效果
     Mat imageLog;

     if(input.channels()==1)
     {
        imageLog=Mat(input.size(), CV_32FC1);
        for (int i = 0; i < input.rows; i++)
        {
            for (int j = 0; j < input.cols; j++)
            {
                imageLog.at<uchar>(i, j) =6*log((double)(input.at<uchar>(i, j))+1);
                //对数变换 s=6*log(r+1)
            }
        }
     }
     else
     {
        imageLog=Mat(input.size(), CV_32FC3);
        for (int i = 0; i < input.rows; i++)
        {
            for (int j = 0; j < input.cols; j++)
            {
                imageLog.at<Vec3f>(i, j)[0] = log(1 + input.at<Vec3b>(i, j)[0]);
                imageLog.at<Vec3f>(i, j)[1] = log(1 + input.at<Vec3b>(i, j)[1]);
                imageLog.at<Vec3f>(i, j)[2] = log(1 + input.at<Vec3b>(i, j)[2]);
            }
        }
     }

     //归一化到0~255
     normalize(imageLog, imageLog, 0, 255, NORM_MINMAX);
     //转换成8bit图像显示   数据类型转换到CV_8U
     convertScaleAbs(imageLog, imageLog);
     output=imageLog;
}

《QT 插件化图像算法研究平台》其它内容:

Opencv 图像金字塔 ---- 高斯和拉普拉斯

OpenCV 仿 Photoshop 曲线调整图像亮度与色彩

QT 插件化图像算法软件架构

Opencv 图像暗通道调优去雾

opencv 提取选中区域内指定 hsv 颜色的水印

Opencv 手工选择图片区域去水印

Opencv 基于文字检测去图片水印

QT 插件化图像算法研究平台

Opencv 图像亮度调节的几种方式

Opencv 使用 QT 的线程注意事项

OpenCV(C++/Python)中的图像对齐(ECC)

OpenCV(C++/Python)中的图像对齐(ECC)

OpenCV(C++/Python)中的图像对齐(ECC)

图1。左图:Prokudin Gorskii收藏的图片。右:通道对齐的同一图像

图1 左图:Prokudin Gorskii收藏的图片。右:通道对齐的同一图像

  左边的这张照片是名为普罗库丁-戈尔斯基(Prokudin-Gorskii)的历史照片集的一部分。这张照片是一位俄罗斯摄影师在20世纪初用早期的彩色相机拍摄的。由于相机的机械特性,图像的颜色通道未对齐。右侧的图像是同一个图像使用OpenCV 3中提供的功能使通道对齐之后的版本。

OpenCV中的运动模型

  在一个典型的图像对齐问题中,我们有一个场景的两幅图像,它们通过一个运动模型相关联。不同的图像对齐算法使用不同的技巧和假设来估计这些运动模型的参数。一旦知道了这些参数,就可以直接对一张图像进行扭曲,使其与另一张图像对齐。让我们快速看看这些运动模型是什么样子的。

在这里插入图片描述

图2 这显示了一个正方形的图像如何通过不同的运动模型进行转换。

  1. Translation ( MOTION_TRANSLATION ):将第一幅图像平移(x, y)得到第二幅图像。我们只需要估算两个参数x和y。
  2. Euclidean ( MOTION_EUCLIDEAN ) :第一幅图像是第二幅图像的旋转和移位版本。所以有三个参数——x,y和角度。你会注意到在图2中,当一个正方形经过欧几里德(Euclidean)变换时,大小不变,平行线保持平行,直角在变换后保持不变。
  3. Affine ( MOTION_AFFINE ):仿射变换是旋转、平移、缩放和剪切的组合。该变换有六个参数。当正方形经过仿射变换时,平行线保持平行,但以直角相交的线不再保持正交。
  4. Homography ( MOTION_HOmogRAPHY ) :上述所有变换都是2D变换。它们不考虑3D效果。而单应性变换则可以解释一些3D效果(但不是全部)。该转换有8个参数。使用单应变换时,正方形可以变成任何四边形。

   在OpenCV中,仿射变换存储在2x3大小的矩阵中。平移变换和欧氏变换是仿射变换的特例。在平移变换中,旋转、缩放和剪切参数为零,而在欧几里得变换中,缩放和剪切参数为零。因此,平移和欧几里得变换也存储在2x3矩阵中。一旦估计出这个矩阵(我们将在下一节中看到),就可以使用warpAffine函数使图像对齐。而单应性变换存储在3 × 3矩阵中。一旦对单应性进行了估计,就可以使用warpPerspective函数对图像进行对齐。

基于增强型相关系数(ECC)最大化的图像配准

  OpenCV 3中引入的ECC图像对齐算法基于2008年Georgios D.Evangelidis和emmanouil Z.PSarakis发表的一篇题为《 Parametric Image Alignment using Enhanced Correlation
Coefficient maximization》的论文。他们建议使用一种名为增强相关系数(ECC)的新相似性度量来估计运动模型的参数。他们的方法有两个优点。

1. 与传统的像素亮度差异相似性度量不同,ECC在对比度和亮度上不受光度失真的影响。
2. 虽然目标函数是参数的非线性函数,但他们提出的求解优化问题的迭代格式是线性的。换句话说,他们把一个表面上看起来计算成本很高的问题,找到了一种更简单的迭代求解方法。

OpenCV中的findTransformECC示例

  在OpenCV 3中,使用函数findTransformECC估计ECC图像对齐的运动模型。以下是使用findTransformECC的步骤

  1. 读入图片;
  2. 将它们转换为灰度图像;
  3. 选择您想要估计的运动模型;
  4. 分配空间(WARP_MATRIX)存储运动模型;
  5. 定义一个终止条件,告诉算法何时停止;
  6. 使用findTransformECC估计扭曲矩阵(warp matrix);
  7. 将扭曲矩阵(warp matrix)应用于其中一幅图像,使其与另一幅图像对齐。

  让我们深入研究代码,看看如何使用它。

C++代码

// Read the images to be aligned
Mat im1 = imread("images/image1.jpg");
Mat im2 = imread("images/image2.jpg");

// Convert images to gray scale;
Mat im1_gray, im2_gray;
cvtColor(im1, im1_gray, CV_BGR2GRAY);
cvtColor(im2, im2_gray, CV_BGR2GRAY);

// Define the motion model
const int warp_mode = MOTION_EUCLIDEAN;

// Set a 2x3 or 3x3 warp matrix depending on the motion model.
Mat warp_matrix;

// Initialize the matrix to identity
if ( warp_mode == MOTION_HOmogRAPHY )
    warp_matrix = Mat::eye(3, 3, CV_32F);
else
    warp_matrix = Mat::eye(2, 3, CV_32F);

// Specify the number of iterations.
int number_of_iterations = 5000;

// Specify the threshold of the increment
// in the correlation coefficient between two iterations
double termination_eps = 1e-10;

// Define termination criteria
TermCriteria criteria (TermCriteria::COUNT+TermCriteria::EPS, number_of_iterations, termination_eps);

// Run the ECC algorithm. The results are stored in warp_matrix.
findTransformECC(
                 im1_gray,
                 im2_gray,
                 warp_matrix,
                 warp_mode,
                 criteria
             );

// Storage for warped image.
Mat im2_aligned;

if (warp_mode != MOTION_HOmogRAPHY)
    // Use warpAffine for Translation, Euclidean and Affine
    warpAffine(im2, im2_aligned, warp_matrix, im1.size(), INTER_LINEAR + WARP_INVERSE_MAP);
else
    // Use warpPerspective for Homography
    warpPerspective (im2, im2_aligned, warp_matrix, im1.size(),INTER_LINEAR + WARP_INVERSE_MAP);

// Show final result
imshow("Image 1", im1);
imshow("Image 2", im2);
imshow("Image 2 Aligned", im2_aligned);
waitKey(0);

重建Prokudin-Gorskii彩色藏品

在这里插入图片描述

  上图也是普罗库丁-戈尔斯基收藏的一部分。左侧是未对齐RGB通道的图像,右侧是对齐后的图像。这张照片还表明,到了20世纪初,照相底片已经足够灵敏,能够漂亮地捕捉到广泛的彩色光谱。鲜艳的红色、蓝色和绿色令人惊叹。

  前一节的代码可以用来解决一个简单的问题。然而,如果你用它来重建上面的图像,你会非常失望。现实世界中的计算机视觉是困难的,事情往往不是真的开箱即用。

  问题是,图像中的红色、绿色和蓝色通道在像素强度方面的相关性并不像您可能猜测的那样强。然而,尽管强度不同,但这三个通道中的一些东西是相似的,因为人眼很容易分辨出这是同一个场景。结果表明,图像的三个通道在梯度域中的相关性更强。这并不奇怪,因为尽管三个通道中的强度可能不同,但由对象和颜色边界生成的边缘贴图是一致的。

  下面给出图像梯度的近似值

C++代码

using namespace cv;
using namespace std;

Mat GetGradient(Mat src_gray)
{
  Mat grad_x, grad_y;
  Mat abs_grad_x, abs_grad_y;
  
  int scale = 1;
  int delta = 0;
  int ddepth = CV_32FC1; ;

  // Calculate the x and y gradients using Sobel operator
  Sobel( src_gray, grad_x, ddepth, 1, 0, 3, scale, delta, BORDER_DEFAULT );
  convertScaleAbs( grad_x, abs_grad_x );

  Sobel( src_gray, grad_y, ddepth, 0, 1, 3, scale, delta, BORDER_DEFAULT );
  convertScaleAbs( grad_y, abs_grad_y );
  
  // Combine the two gradients
  Mat grad;
  addWeighted( abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad );

  return grad; 

}

  现在我们准备重建彩色图片!请阅读下面的内联注释

C++代码

 

using namespace cv;
using namespace std;

// Read 8-bit color image.
// This is an image in which the three channels are
// concatenated vertically.
Mat im =  imread("images/emir.jpg", IMREAD_GRAYSCALE);

// Find the width and height of the color image
Size sz = im.size();
int height = sz.height / 3;
int width = sz.width; 

// Extract the three channels from the gray scale image
vector<Mat>channels;
channels.push_back(im( Rect(0, 0,         width, height)));
channels.push_back(im( Rect(0, height,    width, height)));
channels.push_back(im( Rect(0, 2*height,  width, height))); 

// Merge the three channels into one color image
Mat im_color;
merge(channels,im_color);

// Set space for aligned image.
vector<Mat> aligned_channels;
aligned_channels.push_back(Mat(height, width, CV_8UC1));
aligned_channels.push_back(Mat(height, width, CV_8UC1));

// The blue and green channels will be aligned to the red channel.
// So copy the red channel
aligned_channels.push_back(channels[2].clone());

// Define motion model
const int warp_mode = MOTION_AFFINE;

// Set space for warp matrix.
Mat warp_matrix;

// Set the warp matrix to identity.
if ( warp_mode == MOTION_HOmogRAPHY )
    warp_matrix = Mat::eye(3, 3, CV_32F);
else
    warp_matrix = Mat::eye(2, 3, CV_32F);

// Set the stopping criteria for the algorithm.
int number_of_iterations = 5000;
double termination_eps = 1e-10;

TermCriteria criteria(TermCriteria::COUNT+TermCriteria::EPS,
                          number_of_iterations, termination_eps);

// Warp the blue and green channels to the red channel
for ( int i = 0; i < 2; i++)
{
   double cc = findTransformECC (
                   GetGradient(channels[2]),
                   GetGradient(channels[i]),
                   warp_matrix,
                   warp_mode,
                   criteria
               );

   if (warp_mode == MOTION_HOmogRAPHY)
     // Use Perspective warp when the transformation is a Homography
     warpPerspective (channels[i], aligned_channels[i], warp_matrix, aligned_channels[0].size(), INTER_LINEAR + WARP_INVERSE_MAP);
   else
      // Use Affine warp when the transformation is not a Homography
      warpAffine(channels[i], aligned_channels[i], warp_matrix, aligned_channels[0].size(), INTER_LINEAR + WARP_INVERSE_MAP);

} 

// Merge the three channels
Mat im_aligned;
merge(aligned_channels, im_aligned);

// Show final output
imshow("Color Image", im_color);
imshow("Aligned Image", im_aligned);
waitKey(0);

进一步改进

  如果您要真正制作一个商业图像配准产品,您需要做的工作要比我的代码所做的多得多。例如,当不对齐很大时,此代码可能会失败。在这种情况下,需要在较低分辨率版本的图像上估计扭曲参数,并使用在低分辨率版本中估计的参数初始化较高分辨率版本的扭曲矩阵。此外,findTransformECC估计单个全局变换以进行对齐。当图像中存在局部运动(例如,被摄体在两张照片中略有移动)时,该运动模型显然是不合适的。在这种情况下,需要使用例如基于光流的方法进行附加的局部对准。

转载翻译自下面的链接:https://learnopencv.com/image-alignment-ecc-in-opencv-c-python/

(https://learnopencv.com/image-alignment-ecc-in-opencv-c-python/)

opencv::调整图像亮度与对比度

opencv::调整图像亮度与对比度

 

 

图像变换可以看作如下:
 - 像素变换 – 点操作
 - 邻域操作 – 区域

调整图像亮度和对比度属于像素变换-点操作

 

//创建一张跟原图像大小和类型一致的空白图像、像素值初始化为0
Mat new_image = Mat::zeros( image.size(), image.type() );  

//确保值大小范围为0~255之间
saturate_cast<uchar>(value)

//给每个像素点每个通道赋值
Mat.at<Vec3b>(y,x)[index]=value

 

int main(int argc, char** argv) {

    Mat src, dst;
    src = imread(STRPAHT2);
    if (!src.data) {
        printf("could not load image...\n");
        return -1;
    }
    char input_win[] = "input image";
    cvtColor(src, src, CV_RGB2GRAY);
    namedWindow(input_win, CV_WINDOW_AUTOSIZE);
    imshow(input_win, src);

    int height = src.rows;
    int width = src.cols;
    //创建一张跟原图像大小和类型一致的空白图像、像素值初始化为0
    dst = Mat::zeros(src.size(), src.type());
    float alpha = 1.2;
    float beta = 30;

    Mat m1;
    src.convertTo(m1, CV_32F);
    for (int row = 0; row < height; row++) {
        for (int col = 0; col < width; col++) {
            if (src.channels() == 3) {
                float b = m1.at<Vec3f>(row, col)[0];// blue
                float g = m1.at<Vec3f>(row, col)[1]; // green
                float r = m1.at<Vec3f>(row, col)[2]; // red

                // output
                dst.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(b*alpha + beta);
                dst.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(g*alpha + beta);
                dst.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(r*alpha + beta);
            }
            else if (src.channels() == 1) {
                float v = src.at<uchar>(row, col);
                dst.at<uchar>(row, col) = saturate_cast<uchar>(v*alpha + beta);
            }
        }
    }

    char output_title[] = "contrast and brightness change demo";
    namedWindow(output_title, CV_WINDOW_AUTOSIZE);
    imshow(output_title, dst);

    waitKey(0);
    return 0;
}

 

今天的关于如何使用Python + OpenCV的快速变化的图像亮度?python opencv调整图片亮度的分享已经结束,谢谢您的关注,如果想了解更多关于OpenCV Python:3通道float32图像读取的快速解决方案?、Opencv 图像亮度调节的几种方式、OpenCV(C++/Python)中的图像对齐(ECC)、opencv::调整图像亮度与对比度的相关知识,请在本站进行查询。

本文标签: