org.openpnp.vision.pipeline.stages.HistogramEqualizeAdaptive

功能

用于对图像的指定通道进行对比度受限的自适应直方图均衡化(CLAHE, Contrast Limited Adaptive Histogram Equalization)。与普通的 HistogramEqualize 不同,CLAHE 将图像分割成多个小块(tiles),在每个小块内分别进行直方图均衡化,并限制对比度的放大倍数,从而避免放大图像噪声和过度增强局部对比度。该阶段适用于光照不均匀、局部阴影明显的图像。

参数

参数名 类型 默认值 描述
channelsToEqualize ChannelsToEqualize All 选择需要均衡化的通道。对于灰度图像此参数无效。可选值:FirstSecondThirdFirstAndSecondFirstAndThirdSecondAndThirdAll
clipLimit Double 2.0 对比度限制阈值。值越低,限制越强(抑制噪声但对比度提升有限);值越高,允许的对比度增强越强,但可能放大噪声。
numberOfTileRows int 10 图像在垂直方向上分割的行数(tile 行数)。
numberOfTileCols int 16 图像在水平方向上分割的列数(tile 列数)。

例子 - 灰度图

import cv2
import numpy as np

def generate_nonuniform_illumination_image(output_path="nonuniform.png", size=(640, 480)):
    # 创建从暗 (50) 到亮 (200) 的线性渐变背景
    bg = np.zeros((size[1], size[0]), dtype=np.uint8)
    for y in range(size[1]):
        for x in range(size[0]):
            # 亮度随 x+y 增加,产生对角线渐变
            val = 50 + int(150 * (x + y) / (size[0] + size[1]))
            bg[y, x] = min(255, val)
    
    # 创建中央椭圆区域(前景),亮度与背景相近(轻微差异)
    fg_mask = np.zeros((size[1], size[0]), dtype=np.uint8)
    center = (size[0]//2, size[1]//2)
    axes = (150, 100)
    angle = 30
    cv2.ellipse(fg_mask, center, axes, angle, 0, 360, 255, -1)
    
    # 在椭圆内赋予与背景稍有不同的亮度(模拟低对比度物体)
    result = bg.copy()
    mask = fg_mask > 0
    # 椭圆内亮度 = 背景亮度 * 0.9 + 30,产生细微差异
    ellipse_brightness = (bg[mask].astype(np.float32) * 0.9 + 30).astype(np.uint8)
    result[mask] = ellipse_brightness
    
    # 添加轻微高斯噪声(模拟真实图像)
    noise = np.random.normal(0, 5, result.shape).astype(np.int16)
    result = np.clip(result.astype(np.int16) + noise, 0, 255).astype(np.uint8)
    
    cv2.imwrite(output_path, result)
    print(f"非均匀光照测试图片已生成: {output_path}")

if __name__ == "__main__":
    generate_nonuniform_illumination_image()

<cv-pipeline>
   <stages>
      <cv-stage class="org.openpnp.vision.pipeline.stages.ImageRead" name="read" enabled="true" file="D:\3rd\openpnp_prj\openpnp-official\openpnp-test-images\my_test\nonuniform.png" color-space="Bgr" handle-as-captured="false"/>
      <cv-stage class="org.openpnp.vision.pipeline.stages.ConvertColor" name="gray" enabled="true" conversion="Bgr2Gray"/>
      <cv-stage class="org.openpnp.vision.pipeline.stages.HistogramEqualizeAdaptive" name="equalizeCLAHE" enabled="true" channels-to-equalize="All" clip-limit="2.0" number-of-tile-rows="8" number-of-tile-cols="8"/>
      <cv-stage class="org.openpnp.vision.pipeline.stages.ImageWrite" name="saveCLAHE" enabled="true" file="output_clahe_equalized.png"/>
   </stages>
</cv-pipeline>

效果

在这里插入图片描述
在这里插入图片描述

例子 - 彩色图像

import cv2
import numpy as np

def generate_color_nonuniform_image(output_path="color_nonuniform.png", size=(640, 480)):
    # 创建渐变背景(BGR),亮度从左上到右下逐渐升高
    bg = np.zeros((size[1], size[0], 3), dtype=np.uint8)
    for y in range(size[1]):
        for x in range(size[0]):
            brightness = int(50 + 150 * (x + y) / (size[0] + size[1]))
            # 背景色调为蓝绿色(B稍高,G中等,R低)
            bg[y, x] = (brightness, brightness//2 + 30, brightness//4)
    
    # 前景掩码:椭圆区域
    fg_mask = np.zeros((size[1], size[0]), dtype=np.uint8)
    center = (size[0]//2, size[1]//2)
    axes = (180, 120)
    angle = 30
    cv2.ellipse(fg_mask, center, axes, angle, 0, 360, 255, -1)
    
    # 前景:红色调,但亮度与背景相近(低对比度)
    result = bg.copy()
    mask = fg_mask > 0
    # 红色通道亮度 = 背景平均亮度 * 0.9 + 30,G和B更低
    bg_mean = bg[mask].mean(axis=1).astype(np.float32)
    r = (bg_mean * 0.8 + 40).astype(np.uint8)
    g = (bg_mean * 0.5 + 20).astype(np.uint8)
    b = (bg_mean * 0.3 + 10).astype(np.uint8)
    result[mask, 2] = r   # R
    result[mask, 1] = g   # G
    result[mask, 0] = b   # B
    
    # 添加轻微噪声
    noise = np.random.normal(0, 4, result.shape).astype(np.int16)
    result = np.clip(result.astype(np.int16) + noise, 0, 255).astype(np.uint8)
    
    cv2.imwrite(output_path, result)
    print(f"彩色非均匀光照测试图片已生成: {output_path}")

if __name__ == "__main__":
    generate_color_nonuniform_image()

<cv-pipeline>
   <stages>
      <cv-stage class="org.openpnp.vision.pipeline.stages.ImageRead" name="read" enabled="true" file="D:\3rd\openpnp_prj\openpnp-official\openpnp-test-images\my_test\color_nonuniform.png" color-space="Bgr" handle-as-captured="false"/>
      <cv-stage class="org.openpnp.vision.pipeline.stages.ConvertColor" name="bgr2hsv" enabled="true" conversion="Bgr2Hsv"/>
      <cv-stage class="org.openpnp.vision.pipeline.stages.HistogramEqualizeAdaptive" name="claheV" enabled="true" channels-to-equalize="Third" clip-limit="15.0" number-of-tile-rows="8" number-of-tile-cols="8"/>
      <cv-stage class="org.openpnp.vision.pipeline.stages.ConvertColor" name="hsv2bgr" enabled="true" conversion="Hsv2Bgr"/>
      <cv-stage class="org.openpnp.vision.pipeline.stages.ImageWrite" name="saveCorrect" enabled="true" file="output_clahe_correct.png"/>
   </stages>
</cv-pipeline>

效果

在这里插入图片描述
在这里插入图片描述

END

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐