图像中的天空区域检测!

C# OpenCvSharp 矩阵计算-determinant、trace、eigen、calcCovarMatrix、solve determinant - 计算行列式 trace - 计算矩阵的迹 eigen - 计算特征值和特征向量 calcCovarMatrix - 计算协方差矩阵 solve - 计算线性方程的解 阅读详情
AI摘要

本文提供基于传统视觉算法提取图像中天空区域的方法。先使用sobel算子提取梯度信息图确定边界线,用能量函数优化,还会进行聚类分析等。指出原算法存在的问题并给出改进思路,最后展示了Python代码实现及效果。

一、引言

       天空区域作为图像中的背景信息,为机器人导航、自动驾驶等领域的图像理解提供了重要依据,因此如何检测图像中的天空区域非常重要,本文提供了一个基于传统视觉算法(非机器学习方法)的提取天空区域的方法,参考文献:https://journals.sagepub.com/doi/pdf/10.5772/56884

二、算法思路

1.使用sobel算子为图像提取梯度信息图,从梯度信息图中根据给定阈值提取天空的边界线

于是,天空区域和地面区域可以表示如下:

2.使用一个能量函数作为适应度函数,来优化提取天空边界线,当能量函数最大时,天空边界线最准确

3.通过检测边界线是否发生大的跳变来判断提取的天空区域包含大量建筑,若是,对天空区域进行聚类分析,分为两类,通过与非天空区域的马氏距离来得到真实的天空区域。

4.扫描每一列的像素,通过每一列像素与真实天空区域的马氏距离来判断该像素是否属于天空的像素,从而可以改善天空边界线

算法是这样假设的:

(1)图像中的天空区域在图像的上方

(2)天空区域的像素变化比较平滑

然而实际的城市道路中由于电线杆、红路灯杆等的存在,以及太阳、云彩的影响,会使得天空边界线的提取被阻挡。而且上述假设在很多情况下不成立。此外能量函数只是表明了同一区域的同质性,而实际图像内容的情况比这要复杂的多。

我的改进:

(1)对梯度图像进行阈值分割,可以使得天空的提取鲁棒性更强

(2)使用多项式拟合修正错误的边界线(只是一个实验性的想法)

(3)计算真实天空区域的像素的R、G、B均值,通过对每一列的像素的RGB各通道像素值与天空区域的RGB均值比较,可以得到更完整的天空边界线

三、代码实现

      下面是我的python代码实现,写的不够好,大家适当参考吧,里面部分代码仅仅是为了实现论文中的算法而已。有些经过我改进后的函数,比如梯度信息提取函数,已经不需要再使用extract_border_optimal()函数了。

       大家有什么问题、建议和更好的改进方法请留言评论,我将感激不尽。代码中增加了计算天空消失点的程序,当然通过天空区域判断消失点肯定没有通过车道线计算消失点的准确性更强,但是车道线的检测难度较大,这个问题留待以后再考虑吧!

import cv2
import os
import math
import time
import sys
import numpy as np
import matplotlib.pyplot as plt
from numba import jit
from scipy import spatial
from scipy.optimize import curve_fit


#加载原始图像
def load_image(image_file_path):

    if not os.path.exists(image_file_path):
        print("图像文件不存在!")
        #sys.exit()
    else:
        img = cv2.imread(image_file_path)
        if img is None:
            print('读取图像失败!')
            #sys.exit()
        else:
            return img

#提取图像天空区域
def extract_sky(src_image):

    height, width = src_image.shape[0:2]

    sky_border_optimal = extract_border_optimal(src_image)
    border_correct = correct_border_polynomial(sky_border_optimal,src_image)
    sky_exists = has_sky_region(sky_border_optimal, height / 30, height / 10, 5)

    if sky_exists == 0:
        print('没有检测到天空区域')
        #sys.exit()

    """
    if has_partial_sky_region(border_correct, width / 3):
        border_new = refine_border(border_correct, src_image)
        sky_mask = make_sky_mask(src_image, border_new,1)
        return sky_mask, sky_exists
        #sky_image = display_sky_region(src_image, sky_border_optimal)
    """


    sky_mask = make_sky_mask(src_image, border_correct, 1)

    return sky_mask, sky_exists

#检测图像天空区域
def detect(image_file_path, output_path):

    #加载图像
    src_image = load_image(image_file_path)
    src_image = cv2.pyrDown(src_image)
    #x, y = src_image.shape[0:2]
    #src_image = cv2.resize(src_image, (int(2*y/3),int(2*x/3)), cv2.INTER_CUBIC)

    #提取图像天空区域
    sky_mask,sky_exists = extract_sky(src_image)

    #制作掩码输出
    tic = time.time()
    height = src_image.shape[0]
    width = src_image.shape[1]

    """
    sky_image_full = np.zeros(src_image.shape, dtype= np.uint8)
    for row in range(height):
        for col in range(width):
            if sky_mask[row, col] != 0:
                sky_image_full[row, col, 0] = 0
                sky_image_full[row, col, 1] = 0
                sky_image_full[row, col, 2] = 255

    sky_image = cv2.addWeighted(src_image, 1, sky_image_full, 1, 0)
    """

    for row in range(height):
        for col in range(width):
            if sky_mask[row, col] != 0:
                src_image[row, col, 0] = 0
                src_image[row, col, 1] = 0
                src_image[row, col, 2] = 255

    cv2.imwrite(output_path, src_image)
    toc = time.time()
    print('display mask time: ',(toc - tic), 's')
    print('图像检测完毕!')

#检测图像天空区域--批量
def batch_detect(image_dir, output_dir):

    img_filelist = os.listdir(image_dir)

    print('开始批量提取天空区域')
    i = 1
    for img_file in img_filelist:
        src_img = load_image(image_dir + img_file)
        src_img = cv2.pyrDown(src_img)

        sky_mask,sky_exists = extract_sky(src_img)
        if sky_exists == 0:
            i += 1
            cv2.imwrite(output_dir+img_file, src_img)
            continue
        height = src_img.shape[0]
        width  = src_img.shape[1]

        #sky_image_full = np.zeros(src_img.shape,dtype= src_img.dtype)
        for row in range(height):
            for col in range(width):
                if sky_mask[row, col] != 0:
                    src_img[row, col, 0] = 0
                    src_img[row, col, 1] = 0
                    src_img[row, col, 2] = 255
        #sky_img = cv2.addWeighted(src_img, 1, sky_image_full, 1, 0)
        cv2.imwrite(output_dir+img_file, src_img)

        print('已提取完成第',i,'张')
        i += 1

    print('批量提取完毕')

#计算天空灭点
def compute_vanish(image_file_path):
    # 加载图像
    src_img = load_image(image_file_path)
    src_img = cv2.pyrDown(src_img)
    src_img = cv2.pyrDown(src_img)
    height, width = src_img.shape[0:2]

    # 计算天空边界线
    sky_border_optimal = extract_border_optimal(src_img)
    border_correct = correct_border_polynomial(sky_border_optimal, src_img)

    # 判断是否存在天空
    sky_exists = has_sky_region(border_correct, height / 30, height / 10, 5)
    if sky_exists == 0:
        #print('没有检测到天空区域')
        #cv2.imwrite(output_path, src_img)
        return 2*(src_img.shape[0]//3)-15

    # 计算天空消失点的高度,并画图
    vanish_h = refine_vanishpoint(border_correct, src_img)
    #cv2.circle(src_img, (src_img.shape[1]//2, vanish_h), 4, (0, 255, 0), 8)
    #cv2.imwrite(output_path, src_img)

    return 2*vanish_h

#计算天空灭点--批量
def batch_compute_vanish(image_dir, output_dir):

    vanishs = []
    img_filelist = sorted(os.listdir(image_dir))

    print('开始批量计算天空灭点')
    i = 1
    for img_file in img_filelist:
        #加载图像
        src_image = load_image(image_dir + img_file)
        src_img = cv2.pyrDown(src_image)
        height, width = src_img.shape[0:2]

        #计算天空边界线
        sky_border_optimal = extract_border_optimal(src_img)
        border_correct = correct_border_polynomial(sky_border_optimal, src_img)

        #判断是否存在天空
        sky_exists = has_sky_region(border_correct, height / 30, height / 10, 5)
        if sky_exists == 0:
            print('没有检测到天空区域')
            i += 1
            cv2.imwrite(output_dir + img_file, src_image)
            continue

        #计算天空消失点的高度,并画图
        vanish_h = refine_vanishpoint(border_correct, src_img)
        vanishs.append(2*vanish_h)
        cv2.circle(src_image, (src_image.shape[1]//2, 4*vanish_h), 4, (0, 255, 0), 8)
        cv2.imwrite(output_dir+img_file, src_image)

        print('已计算完成第',i,'张')
        i += 1

    print('批量计算完毕')
    return vanishs

#提取图像梯度信息
def extract_image_gradient(src_image):
    #转灰度图像
    gray_image = cv2.cvtColor(src_image, cv2.COLOR_BGR2GRAY)

    #Sobel算子提取图像梯度信息
    x_gradient = cv2.Sobel(gray_image, cv2.CV_64F, 1, 0, 3)
    y_gradient = cv2.Sobel(gray_image, cv2.CV_64F, 0, 1, 3)

    #计算梯度幅值
    gradient_image = np.hypot(x_gradient, y_gradient)
    ret, gradient_image = cv2.threshold(gradient_image, 40, 1000, cv2.THRESH_BINARY)
    #gradient_image = np.uint8(np.sqrt(np.multiply(x_gradient,x_gradient) + np.multiply(y_gradient,y_gradient)))

    return gradient_image

#利用能量函数优化计算计算天空边界线
def extract_border_optimal(src_image, thres_sky_min = 5, thres_sky_max = 600, thres_sky_search_step = 6):

    #提取梯度信息图
    gradient_info_map = extract_image_gradient(src_image)

    n = math.floor((thres_sky_max - thres_sky_min)/ thres_sky_search_step) + 1

    border_opt = None
    jn_max = 0

    for i in range(n + 1):
        t = thres_sky_min + (math.floor((thres_sky_max - thres_sky_min) / n) - 1) * i
        b_tmp = extract_border(gradient_info_map, t)
        jn = calculate_sky_energy(b_tmp, src_image)
        #print('threshold= ',t,'energy= ',jn)

        if jn > jn_max:
            jn_max = jn
            border_opt = b_tmp

    return border_opt

# 计算天空图像能量函数
def calculate_sky_energy(border, src_image):

    # 制作天空图像掩码和地面图像掩码
    sky_mask = make_sky_mask(src_image, border, 1)
    ground_mask = make_sky_mask(src_image, border, 0)

    # 扣取天空图像和地面图像
    sky_image_ma = np.ma.array(src_image, mask = cv2.cvtColor(sky_mask, cv2.COLOR_GRAY2BGR))
    ground_image_ma = np.ma.array(src_image, mask = cv2.cvtColor(ground_mask, cv2.COLOR_GRAY2BGR))

    # 计算天空和地面图像协方差矩阵
    sky_image = sky_image_ma.compressed()
    ground_image = ground_image_ma.compressed()

    sky_image.shape = (sky_image.size//3, 3)
    ground_image.shape = (ground_image.size//3, 3)

    sky_covar, sky_mean = cv2.calcCovarMatrix(sky_image, mean=None, flags=cv2.COVAR_ROWS|cv2.COVAR_NORMAL|cv2.COVAR_SCALE)
    sky_retval, sky_eig_val, sky_eig_vec = cv2.eigen(sky_covar)

    ground_covar, ground_mean = cv2.calcCovarMatrix(ground_image, mean=None,flags=cv2.COVAR_ROWS|cv2.COVAR_NORMAL|cv2.COVAR_SCALE)
    ground_retval, ground_eig_val, ground_eig_vec = cv2.eigen(ground_covar)

    gamma = 2  # 论文原始参数

    sky_det = cv2.determinant(sky_covar)
    #sky_eig_det = cv2.determinant(sky_eig_vec)
    ground_det = cv2.determinant(ground_covar)
    #ground_eig_det = cv2.determinant(ground_eig_vec)

    sky_energy = 1 / ((gamma * sky_det + ground_det) + (gamma * sky_eig_val[0,0] + ground_eig_val[0,0]))

    return sky_energy

# 判断图像是否存在天空区域
def has_sky_region(border, thresh_1, thresh_2, thresh_3):

    border_mean = np.average(border)

    #求天际线位置差,取绝对值,取均值
    border_diff_mean = np.average(np.absolute(np.diff(border)))

    sky_exists = 0
    if border_mean < thresh_1 or (border_diff_mean > thresh_3 and border_mean < thresh_2):
        return sky_exists
    else:
        sky_exists = 1
        return sky_exists

#判断图像是否有部分区域为天空区域
def has_partial_sky_region(border, thresh_4):

    border_diff = np.diff(border)

    '''
    if np.any(border_diff > thresh_4):
        index = np.argmax(border_diff)
        print(border_diff[index])
    '''

    return np.any(border_diff > thresh_4)

#计算天空边界线
def extract_border(gradient_info_map, thresh):

    height, width = gradient_info_map.shape[0:2]
    border = np.full(width, height - 1)

    for col in range(width):
        #返回该列第一个大于阈值的元素的索引
        border_pos = np.argmax(gradient_info_map[:, col] > thresh)
        if border_pos > 0:
            border[col] = border_pos

    return border

#天空区域和原始图像融合图,显示天空区域
def display_sky_region(src_image, border):

    height = src_image.shape[0]
    width = src_image.shape[1]

    #制作天空图掩码
    sky_mask = make_sky_mask(src_image, border, 1)

    #天空和原始图像融合
    sky_image_full = np.zeros(src_image.shape, dtype = src_image.dtype)
    for row in range(height):
        for col in range(width):
            if sky_mask[row, col] != 0:
                src_image[row, col, 0] = 0
                src_image[row, col, 1] = 0
                src_image[row, col, 2] = 255
    sky_image = cv2.addWeighted(src_image, 1, sky_image_full, 1, 0)

    return sky_image

#制作天空掩码图像,type: 1: 天空 0: 地面
def make_sky_mask(src_image, border, type):

    height = src_image.shape[0]
    width = src_image.shape[1]

    mask = np.zeros((height,width),dtype= np.uint8)

    if type == 1:
        for col, row in enumerate(border):
            mask[0:row +1, col] = 255
    elif type == 0:
        for col, row in enumerate(border):
            mask[row + 1:, col] = 255
    else:
        assert type is 0 or type is 1,'type参数必须为0或1'

    return mask

#改善天空边界线
def refine_border(border, src_image):

    sky_covar, sky_mean, ic_s, ground_covar, ground_mean, ic_g = true_sky(border, src_image)

    for col in range(src_image.shape[1]):
        cnt = np.sum(np.greater(spatial.distance.cdist(src_image[0:border[col], col], sky_mean, 'mahalanobis', VI=ic_s), spatial.distance.cdist(src_image[0:border[col], col], ground_mean, 'mahalanobis', VI=ic_g)))

        if cnt < (border[col] / 2):
            border[col] = 0

    return border

#改善天空边界线————alpha版本
def refine_border_alpha(border, src_image):

    sky_covar, sky_mean, ic_s, ground_covar, ground_mean, ic_g = true_sky(border, src_image)

    for col in range(src_image.shape[1]):
        for row in range(src_image.shape[0]):
            mahalanobis_sky = spatial.distance.cdist(src_image[row, col].reshape(1, 3), sky_mean, 'mahalanobis',VI=ic_s)
            mahalanobis_gr = spatial.distance.cdist(src_image[row, col].reshape(1, 3), ground_mean, 'mahalanobis',VI=ic_g)
            delta1 = abs(src_image[row, col, 0] - sky_mean[0,0]) < sky_mean[0,0] / 3.6
            delta2 = abs(src_image[row, col, 1] - sky_mean[0,1]) < sky_mean[0,1] / 3.6
            delta3 = abs(src_image[row, col, 2] - sky_mean[0,2]) < sky_mean[0,2] / 3.6
            if mahalanobis_sky < mahalanobis_gr and delta1 and delta2 and delta3:
                border[col] = row

    """
    sky_mean = np.mean(sky_image_true, axis= 0)
    for col in range(width):
        for row in range(height):
            delta1 = abs(src_image[row,col,0] - sky_mean[0]) < sky_mean[0]/3.6
            delta2 = abs(src_image[row,col,1] - sky_mean[1]) < sky_mean[1]/3.6
            delta3 = abs(src_image[row,col,2] - sky_mean[2]) < sky_mean[2]/3.6
            if delta1 and delta2 and delta3:
                border[col] = row
    """
    return border

#获取更真实天空像素和地面像素的均值、协方差及其逆
def true_sky(border, src_image):

    #制作天空图像掩码和地面图像掩码
    sky_mask = make_sky_mask(src_image, border, 1)
    ground_mask = make_sky_mask(src_image, border, 0)

    #扣取天空图像和地面图像
    sky_image_ma = np.ma.array(src_image, mask = cv2.cvtColor(sky_mask, cv2.COLOR_GRAY2BGR))
    ground_image_ma = np.ma.array(src_image, mask = cv2.cvtColor(ground_mask, cv2.COLOR_GRAY2BGR))

    #将天空和地面区域shape转换为n*3
    sky_image = sky_image_ma.compressed()
    ground_image = ground_image_ma.compressed()

    sky_image.shape = (sky_image.size//3, 3)
    ground_image.shape = (ground_image.size//3, 3)

    # k均值聚类调整天空区域边界--2类
    sky_image_float = np.float32(sky_image)
    criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
    flags = cv2.KMEANS_RANDOM_CENTERS
    compactness, labels, centers = cv2.kmeans(sky_image_float, 2, None, criteria, 10, flags)

    sky_label_0 = sky_image[labels.ravel() == 0]
    sky_label_1 = sky_image[labels.ravel() == 1]

    sky_covar_0, sky_mean_0 = cv2.calcCovarMatrix(sky_label_0, mean= None, flags= cv2.COVAR_ROWS + cv2.COVAR_NORMAL + cv2.COVAR_SCALE)
    sky_covar_1, sky_mean_1 = cv2.calcCovarMatrix(sky_label_1, mean= None, flags= cv2.COVAR_ROWS + cv2.COVAR_NORMAL + cv2.COVAR_SCALE)
    ground_covar, ground_mean = cv2.calcCovarMatrix(ground_image, mean= None, flags= cv2.COVAR_ROWS + cv2.COVAR_NORMAL + cv2.COVAR_SCALE)

    ic_s0 = cv2.invert(sky_covar_0, cv2.DECOMP_SVD)[1]
    ic_s1 = cv2.invert(sky_covar_1, cv2.DECOMP_SVD)[1]
    ic_g = cv2.invert(ground_covar, cv2.DECOMP_SVD)[1]

    #推断真实的天空区域
    if cv2.Mahalanobis(sky_mean_0, ground_mean, ic_s0) > cv2.Mahalanobis(sky_mean_1, ground_mean, ic_s1):
        sky_mean = sky_mean_0
        sky_covar = sky_covar_0
        ic_s = ic_s0
    else:
        sky_mean = sky_mean_1
        sky_covar = sky_covar_1
        ic_s = ic_s1


    return sky_covar,sky_mean,ic_s,ground_covar, ground_mean,ic_g

#修正天空灭点
def refine_vanishpoint(border,src_image):

    src_image = cv2.GaussianBlur(src_image, (7,7), 0)
    index = np.argmax(border)

    if border[index] >= 3*(src_image.shape[0]//4):
        dist = np.full(border[index], 0)
        width = src_image.shape[1]
        sky_covar,sky_mean,ic_s,ground_covar, ground_mean,ic_g = true_sky(border, src_image)
        for row in range(border[index]):
            distance = spatial.distance.cdist(src_image[width // 2, row].reshape(1, 3), sky_mean, 'mahalanobis',VI=ic_s)
            dist[row] = distance
        diff1 = np.diff(dist)
        diff2 = abs(np.diff(diff1))
        vanish_h = np.argmax(diff2)
    elif border[index] < src_image.shape[0]//2 :
        dist = np.full(src_image.shape[0], 0)
        width = src_image.shape[1]
        sky_covar,sky_mean,ic_s,ground_covar, ground_mean,ic_g = true_sky(border, src_image)
        for row in range(src_image.shape[0]):
            distance = spatial.distance.cdist(src_image[width//2, row].reshape(1, 3), sky_mean, 'mahalanobis', VI=ic_s)
            dist[row] = distance
        diff1 = np.diff(dist)
        diff2 = abs(np.diff(diff1))
        vanish_h = np.argmax(diff2)
    else:
        vanish_h = border[index]

    return vanish_h

#修正错误边界线--多项式拟合
def correct_border_polynomial(border, src_image):

    x = np.arange(0, src_image.shape[1], 1)
    border_line_argument = np.polyfit(x, border, 10)
    border_line_function = np.poly1d(border_line_argument)
    border_polynomial = np.int64(border_line_function(x))

    outlier = np.percentile(border,90)
    for col in range(len(border)):
        if border[col] >= outlier: # or abs(border[col]-border_polynomial[col]) > src_image.shape[0]/3 :
            border[col] = border_polynomial[col]
        #elif border[col] <= src_image.shape[0]//3:
            #border[col] = border_polynomial[col]

    return border

'''
#修正错误边界线--二次函数拟合
def correct_border_quardratic(border, src_image):
    outlier = np.percentile(border, 90)
    for col in range(len(border)):
        if border[col] >= outlier:
            if col == 0:
                border[col] = border[col + 1]
            elif col == src_image.shape[1] - 1:
                border[col] = border[col - 1]
            else:
                border[col] = (border[col - 1] + border[col + 1]) / 2
    x = np.arange(0, src_image.shape[1], 1)
    def fun(x,a,b,c):
        return a*(x**2) + b*x +c
    ppot,pcov = curve_fit(fun, x, border)
    a = ppot[0]
    b = ppot[1]
    c = ppot[2]
    border_new = np.int64(fun(x,a,b,c))

    return border_new
'''


if __name__ == '__main__':

    image_file_path = '/home/dulingwen/Pictures/skydetect/images/'
    out_path = '/home/dulingwen/Pictures/skydetect/output/'

    tic = time.time()
    batch_detect(image_file_path, out_path)
    toc = time.time()
    times = 1000*(toc- tic)
    print('运行时间:',times,'ms')

效果如下:

 

基于Matlab图像处理之天空区域识别 一、项目背景与意义在图像处理领域,天空区域的识别具有重要的研究价值和应用前景。天空区域通常具有相对均匀的颜色和纹理,且占据图像中的大部分面积。识别出图像中的天空区域可以用于许多应用场景,如风景图像美化、虚拟现实增强、环境监测等。通过Matlab这一强大的图像处理工具,我们可以实现高效且准确的天空区域识别算法。二、技术原理天空区域识别通常涉及颜色空间分析、纹理特征提取和机器学习分类等技术。在Matlab中,我们可以使用这些技术来构建天空区域识别的算法。 阅读详情

相关推荐

Linux系统监控实战:夜莺监控+categraf采集器配置全流程(附常见问题排查)

本文详细介绍了在Linux系统中使用夜莺监控和categraf采集器进行系统监控的全流程配置,包括环境准备、核心配置文件(如config.toml和procstat.toml)详解、服务集成与验证、高级监控配置实战以及常见问题排查。通过实战案例和优化建议,帮助运维人员快速构建高效的监控体系。

xray4的博客 734

图片天空区域识别

https://blog.youkuaiyun.com/zhubaohua_bupt/article/details/51887339

u013049912的博客 1745

从零到一:OptimizePI Pre-layout PDN前仿真实战指南

本文详细介绍了如何使用OptimizePI进行电源完整性(PDN)前仿真,从软件安装配置到元器件建模、去耦电容配置及仿真参数设置,提供了实战技巧和常见问题排查指南。通过OptimizePI的Pre-layout仿真,工程师可以在PCB布局前优化电源分配网络,显著提升设计效率并降低成本。

weixin_28304023的博客 505

天空区域检测python

https://journals.sagepub.com/doi/pdf/10.5772/56884 ref https://blog.youkuaiyun.com/dulingwen/article/details/92993371?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevan...

qq_35608277的博客 3144

图形化界面无限转圈?CentOS 7的SELinux避坑指南(附命令行修复实录)

本文详细解析了CentOS 7图形界面启动时无限转圈或卡在'starting switch root'的故障原因,主要与SELinux安全策略冲突有关。提供了三种修复方案:临时禁用SELinux、重装策略包和精细调整策略,并分享了长期维护建议,帮助用户平衡系统安全性与可用性。

potato的博客 797

解决Qt平台插件初始化失败:This application failed to start because no Qt platform plugin could be initialized

本文深入解析了Qt应用程序启动时常见的‘platform plugin’初始化失败报错,指出其核心在于环境变量冲突或多版本Qt共存导致的插件路径混乱。文章提供了从环境变量检查、路径调整到文件补全的完整解决方案,并给出了使用windeployqt工具等预防性开发实践,帮助用户和开发者彻底解决这一经典问题。

weixin_29229261的博客 2166

【连通域检测】基于形态学处理的连通区域检测matlab仿真

1,在1X1的一个窗口里生成一定数量,一定直径的圆盘。如果有一组或多组相交或相切圆盘把1X1窗口的左右(或上下)两边连接起来,则形成Percolation这种现象。如没有一组圆盘能将左右(或上下)两侧联系起来则没有Percolation这种现象。 2,输入为:圆盘直径,圆盘数量。输出为:Percolation的路径(在1X1的窗口中显示出那组原判形成了Percolation。比如普通圆盘为绿色,Percolation圆盘为红色) 选择不同的输入模式,例如输入半径为0.2,输入个数为6个。点击DRAW

FPGA/MATLAB学习教程/源码/项目合作开发 1528

【SpringCloud】5、Spring Cloud Gateway网关路由规则

Spring Cloud Gateway 创建 Route 对象时, 使用 RoutePredicateFactory 创建 Predicate 对象,Predicate 对象可以赋值给 Route。

JACKAL 3万+

图像处理之天空区域识别

近几年来,去雾方法得到广泛的研究,汤晓鸥等人发现无雾图像相对于雾化图像具有较高的对比度,通过最大化恢复图像的对比度来实现图像去雾,但由于该方法没有从物理模型上恢复真实的场景反射率,图像去雾后有可能出现颜色过饱和失真。 Kaiming He提出了一种基于暗通道先验的方法,即在有雾图像的特定窗中至少有一个颜色分量的值是零,该算法利用最小值滤波估算出介质传播函数,然后利用软抠图原理对估算的介质传播函数进...

AomanHao的博客 6095

fatal: unable to access ‘https://github.com/Stability-AI/stablediffusion.git/‘解决方案

本文主要介绍在安装 stable-diffusion-webui 时出现的 fatal: unable to access 'https://github.com/Stability-AI/stablediffusion.git/': Failed to connect to github.com port 443 after 21071 ms: Couldn't connect to server 问题的解决方案,希望能对你有所帮助。

水滴的博客 5684

超详细的Burp Suite安装使用

‌Burp Suite是一个强大的Web应用安全测试工具,适用于网络安全专业人士进行自动化网络应用程序的安全测试。‌ 它提供了在Windows和Kali Linux上安装和激活Burp Suite Professional的简便步骤,帮助用户快速集成并启用强大的网络扫描和渗透测试功能。Burp Suite的特点包括易于安装、良好的兼容性、内置的自动化工具、优秀的用户体验以及详细的教程,使得无论是安全领域的新手还是经验丰富的专家,都能轻松上手并高效地进行安全测试。此外,Burp Suite还支持扩展功能的使用

Dreams°的博客 2640

OpenCV-实现天空变换(图像分割)

OpenCV&C++代码实现图像分割——天空更换

翟天保的博客 2万+

【YOLOv11工业级实战】27. TensorRT量化实战:FP16/INT8极致加速!边缘设备YOLOv11推理速度提升4倍,精度损失控制在1.5%内

摘要:本文针对智慧园区200路摄像头实时分析的工业痛点——RTX 3080单卡仅能处理12路视频流(YOLOv11-nano FP32精度45FPS,需≥120FPS且精度损失≤3%),提供TensorRT量化完整解决方案。从原理解析(FP16/INT8精度差异与量化逻辑)到实操落地(ONNX转换、FP16引擎构建、INT8精细校准),全程给出可复用代码。实测显示:FP16量化后速度达128FPS(×2.8),精度损失0.2%。

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 1716

天空分割

第一步我认为最有价值,直接在原始数据判断天空不是很好做,作者观察到天空部分整体来说是比较平滑的,也就是相邻像素之间变化不大,因此用梯度来表示则更容易识别,梯度值越小则表明图像那一块越光滑。 第二步则设定一个阈值来初步判断某处是否属于天空,这个阈值作者取的是0.02,量化到unsigned char范围则基本对应5。 第三步对初步的边界进行下小范围的扩展。 第四步对分割后的图的每个联通区域统计其原始...

qq_35608277的博客 4539

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

c++ opencv编程实现暗通道图像去雾算法_图像处理之天空区域识别

近几年来,去雾方法得到广泛的研究,汤晓鸥等人发现无雾图像相对于雾化图像具有较高的对比度,通过最大化恢复图像的对比度来实现图像去雾,但由于该方法没有从物理模型上恢复真实的场景反射率,图像去雾后有可能出现颜色过饱和失真。 Kaiming He提出了一种基于暗通道先验的方法,即在有雾图像的特定窗中至少有一个颜色分量的值是零,该算法利用最小值滤波估算出介质传播函数,然后利用软抠图原理对估算的介质传播函数进...

weixin_42510600的博客 1566

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

基于MATLAB的图像区域特征检测

图像中区域特征检测与提取技术研究 摘要:数字图像处理是利用计算机对图像信息进行各种变换处理的技术和方法。本文主要介绍了数字图像处理和图像中区域特征检测的原理,以及MATLAB在数字图像处理中的应用。本次设计主要研究了数字图像处理中图像分割中的阈值分割法和区域生长法,此次研究主要是以MATLAB软件为平台,采用了区域生长法编写设计代码程序,实现了数字图像的区域特征检测,包括提取了周长、面积和重心坐标,整个设计以区域生长基本算法编写。 关键词:图像分割;区域生长法;MATLAB;区域特征检测

GGMMM123的博客 1038

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

利用OpenCV的SimpleBlobDetector检测图像的奇异区域(斑点)

奇异区域通常是指与周围领域有着某些特征(颜色或灰度)差别的区域。常见的奇异区域如医学领域X光照片或CT某些特定组织、天空中降落的特体等。 奇异区域检测一般采用两种方法来实现。PS:下面对原理的描述只是个大概描述,估计大家都看得模模糊糊的,如果想真得搞清楚,请自行搜索相关论文。之所以要给个大概描述,是方便大家查询资料时有个参考。 ⑴基于微分检测器检测。拉普拉斯算子是检测图像奇异区域常用的方法。图...

昊虹AI笔记 1万+

基于暗通道先验与天空检测的图像去雾算法:原理、实现与优化

图像去雾是计算机视觉中提升图像质量与系统鲁棒性的关键技术,其核心在于解决大气散射导致的图像退化问题。该技术基于大气散射模型,通过估计透射率与大气光成分,从单幅有雾图像中复原出清晰场景。暗通道先验作为一种高效的物理先验,为透射率估计提供了统计基础,但传统方法在处理天空区域时易产生过饱和与光晕伪影。本文深入剖析了一种融合局部香农熵进行鲁棒天空检测的改进暗通道先验方法,通过精准分割天空区域并采用快速引导滤波优化透射图,在保持高去雾质量的同时显著提升了处理速度。该技术可广泛应用于自动驾驶、视频监控与无人机航拍等户外

weixin_33691817的博客 664

避免图像去雾算法中让天空部分出现过增强的一种简易方法

FROM:http://www.chawenti.com/articles/25193.html 在经典的几种去雾算法中,包括何凯明的暗通道去雾、Tarel的基于中值滤波的去雾以及一些基于其他边缘保留的方法中,都有一个普遍存在的问题:即对天空部分处理的不好,天空往往会出现较大的面积的纹理及分块现象。究其主要原因,还是因为天空部位基本上是不符合暗通道去雾先验这个前决条件的。目前,针对这一问题,

凌风探梅的专栏 6415

避免图像去雾算法中让天空部分出现过增强的一种简易方法。

在经典的几种去雾算法中,包括何凯明的暗通道去雾、Tarel的基于中值滤波的去雾以及一些基于其他边缘保留的方法中,都有一个普遍存在的问题:即对天空部分处理的不好,天空往往会出现较大的面积的纹理及分块现象。究其主要原因,还是因为天空部位基本上是不符合暗通道去雾先验这个前决条件的。目前,针对这一问题,我搜索到的主要有以下几篇文章进行了处理:1、 改进的基于暗原色先验的图像去雾算法 作者: 蒋建国\侯天...

storm的博客 3437

偷天换日,逼真的天空置换算法

SkyAR算法是一种用于视频中天空置换与协调的视觉方法,该方法能够在风格可控的视频中自动生成逼真的天空背景。

Jack-Cui 5060

第107期 天空图像分割数据集

引言 亲爱的读者们,您是否在寻找某个特定的数据集,用于研究或项目实践?欢迎您在评论区留言,或者通过公众号私信告诉我,您想要的数据集的类型主题。小编会竭尽全力为您寻找,并在找到后第一时间与您分享。 一、重要性及意义 天空图像分割的研究意义和重要性主要体现在以下几个方面: 目标检测和识别:在图像处理中,天空图像分割可以帮助准确...

weixin_41184918的博客 878

图像中的点、线检测

前言 图像分割是图像处理中非常重要的组成部分,它主要是用于提取我们对图像中感兴趣的部分。而图像分割中最基础的就是对点和线进行提取识别。 一、点检测 针对镶嵌在图像的恒定或近似恒定区域中的孤立点的检测,其实其原理和空间域中的滤波十分相似。本质上是套用模板后,利用模板对原图像进行处理,得到的新图进行阈值处理。如果新图中像素点大于我们的设想阈值,则认为其为我们感兴趣的孤立点而加以保留;反之,若小于阈值则舍去。最后读出图像即可。 对于点检测的模板我们通常使用这个模板:[-1 -1 -1;-1 8...

billzhaobaigu的博客 7302

Luminar 4:一键换天空

“一键智能替换天空,而无需做复杂的蒙版,替换后的天空还能与原图进行很好的光线及氛围的融合。这是目前为止最好的一键换天空的软件。”--PhotoshopTea“哇,天哪,当我在Lumina...

qq_41176800的博客 4203
上一篇: linux安装PCL库
下一篇: SLAM理论
dulingwen
博客等级 码龄9年 519粉丝 72原创
评论 11
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值