You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Matlab转Python的模糊上下文对比度增强代码出现拼图状失真排查

模糊上下文对比度增强算法转Python+OpenCV后拼图状失真的排查与解决

我正在将一篇会议论文中的模糊上下文对比度增强算法从Matlab转为Python+OpenCV版本。处理特定图像时输出出现拼图状失真,其他图像运行正常,原Matlab代码无此问题,请求排查代码故障并解决该失真问题。

相关会议论文、源图、处理后失真图已提供,当前Python代码如下:

import cv2
import math
import numpy as np

image = cv2.imread('img1.bmp')
CIm = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

a=CIm[:,:,2]
Im = a/255
def f1(num):
    return math.floor(num*10000)
Im = np.vectorize(f1)(Im)

rows = Im.shape[0]
cols = Im.shape[1]

Ffactor = np.zeros(Im.shape,dtype = int)
H = np.zeros((10001,1),dtype=float)

w=1

width = round(np.std(Im.astype(float)))
for i in range(rows):
    for j in range(cols):
        
        totf = 0.0
        count = 0 
        f = 0.0
        
        for ii in range(-w,w+1):
            for jj in range(-w,w+1):
                if (i + ii >= 0 and i + ii < rows and j + jj >= 0 and j + jj < cols):
                            count = count + 1 ;
                            temp = float(Im[i + ii,j + jj]) - float(Im[i,j])
                            f = max(min(1-abs(temp/width),1),0)
                            totf = totf + (f)
                            
        t =  totf/9
        print(count)
        Ffactor[i,j] = t
                
        H[Im[i,j]] = H[Im[i,j]] + math.log2(t)**2
Hpdf =  H/np.sum(H)
#total = np.sum(H)
#for k in range(H.shape[0]):
 #   Hpdf[k] = H[k]/total
    
    
def FHE(Im,Ffactor ,Hpdf, lval, hval):
    Hcdf = np.cumsum(Hpdf)
    m=np.mean(Im,dtype=float)
    s=np.std(Im,dtype=float)
    
    delta = s/m
    
    for i in range(Im.shape[0]):
        for j in range(Im.shape[1]):
            temp = lval + round(( hval- lval) * Hcdf[Im[i,j]] )
            Im[i,j] = ((temp - float(Im[i,j])) * math.exp((-(Ffactor[i,j])**2)*1*delta) + Im[i,j])
            
    return Im   

Imf = FHE(Im, Ffactor,Hpdf, 0, 10000)
Imf = Imf/10000
Imf = Imf*255
Imf = np.vectorize(round)(Imf)
CIm[:,:,2] = Imf;
Im_out = cv2.cvtColor(CIm, cv2.COLOR_HSV2BGR)
cv2.imshow('Original image',image)
cv2.imshow('equalised image', Im_out)
   
cv2.waitKey(0)
cv2.destroyAllWindows()

问题根源分析

  1. 数据类型强制截断精度丢失

    • Ffactor被定义为int类型,但计算得到的上下文权重t是浮点数,直接赋值会截断小数部分,导致邻域权重信息严重丢失,这是拼图失真的核心原因。
    • FHE函数直接修改整数类型的Im数组,浮点运算结果被强制转回整数,进一步加剧精度损失。
  2. 边界邻域权重计算错误

    • 计算平均权重t时固定除以9,但边界像素的有效邻域像素数count小于9,错误的权重计算会导致边缘区域出现异常色块。
  3. 低效且易出错的向量操作

    • 使用np.vectorize处理浮点转整数操作,效率低且容易引发隐式类型转换问题。

修复后的代码

import cv2
import math
import numpy as np

image = cv2.imread('img1.bmp')
CIm = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

# 提取亮度通道并归一化处理
a = CIm[:, :, 2]
Im = a / 255
# 用numpy原生floor替代vectorize,避免类型问题且效率更高
Im = np.floor(Im * 10000).astype(np.int32)

rows, cols = Im.shape

# Ffactor改为浮点类型,保留权重小数精度
Ffactor = np.zeros(Im.shape, dtype=np.float32)
H = np.zeros((10001, 1), dtype=np.float32)

w = 1
width = round(np.std(Im.astype(float)))

for i in range(rows):
    for j in range(cols):
        totf = 0.0
        count = 0
        f = 0.0

        for ii in range(-w, w + 1):
            for jj in range(-w, w + 1):
                if 0 <= i + ii < rows and 0 <= j + jj < cols:
                    count += 1
                    temp = float(Im[i + ii, j + jj]) - float(Im[i, j])
                    f = max(min(1 - abs(temp / width), 1), 0)
                    totf += f

        # 用实际有效邻域像素数计算平均权重,修正边界计算错误
        t = totf / count
        Ffactor[i, j] = t

        # 避免t=0时对数运算报错,添加极小值保护
        if t > 0:
            H[Im[i, j]] += math.log2(t) ** 2

Hpdf = H / np.sum(H)

def FHE(Im, Ffactor, Hpdf, lval, hval):
    Hcdf = np.cumsum(Hpdf)
    m = np.mean(Im.astype(float))
    s = np.std(Im.astype(float))
    delta = s / m

    # 创建浮点类型副本,避免修改原整数数组导致精度丢失
    Im_copy = Im.astype(np.float32)
    for i in range(Im_copy.shape[0]):
        for j in range(Im_copy.shape[1]):
            temp = lval + round((hval - lval) * Hcdf[Im[i, j]])
            Im_copy[i, j] = ((temp - float(Im[i, j])) * math.exp(-(Ffactor[i, j] ** 2) * delta) + float(Im[i, j]))

    return Im_copy

Imf = FHE(Im, Ffactor, Hpdf, 0, 10000)
# 反归一化并转换为图像灰度范围
Imf = Imf / 10000 * 255
# 用numpy原生round替代vectorize
Imf = np.round(Imf).astype(np.uint8)

# 替换亮度通道并转回BGR格式
CIm[:, :, 2] = Imf
Im_out = cv2.cvtColor(CIm, cv2.COLOR_HSV2BGR)

cv2.imshow('Original image', image)
cv2.imshow('equalised image', Im_out)
cv2.waitKey(0)
cv2.destroyAllWindows()

关键修复点说明

  • 修正数据类型:将Ffactor改为float32类型,保留上下文权重的小数精度;FHE函数中使用浮点类型数组副本进行运算,避免整数截断。
  • 修复边界计算:用实际有效邻域像素数count替代固定的9计算平均权重,解决边缘区域的失真问题。
  • 优化数值稳定性:添加t>0的判断避免对数运算报错;用numpy原生函数替换np.vectorize,提升效率并避免类型问题。
  • 避免原数组修改:在FHE中操作数组副本,防止原Im数组被修改影响后续计算。

内容的提问来源于stack exchange,提问作者Ankit Raj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 16:01:29