Python处理图片生成天际线(2024.1.29)

news2024/11/22 5:30:50

1、天际线简介

        天际线SkyLine)顾名思义就是天空与地面的边界线,人站在不同的高度,会看到不同的景色和地平线,天空与地面建筑物分离的标记线,不得不说,每天抬头仰望天空,相信大家都可以看到,它的的确确客观存在,美丽值得欣赏。

2、Python代码

#-*- coding:utf-8 -*-
import sys
from os.path import exists
import cv2
import numpy as np

def getImage(height, width, channels):
    image = np.zeros([height, width, 3], np.uint8) # 三通道顺序是BGR
    # 三层循环逐个修改像素点
    for row in range(height):
        for col in range(width):
                for c in range(channels):
                    image[row, col, c] = 0
    return image

def isWhite(pixel_value, threshold): #阈值可以取10、20、30、50、100
    res = False
    if pixel_value[0] > threshold and pixel_value[1] > threshold and pixel_value[2] > threshold: # 10、10、10 50、50、50 这里是天空和地面楼山的分界线,需要调参
        res = True
    return res

def isPureWhite(pixel_value):
    res = False
    if pixel_value[0] == 255 and pixel_value[1] == 255 and pixel_value[2] == 255: # >3|>3|>3 10、10、10
        res = True
    return res

def getRowNumberSpecificCol(image, col):
    res_row = -1
    height, width = image.shape[0:2]
    if col >= 0 and col < width:
        for row in range(0, height):
            pv = image[row][col]
            if(pv[0] > 0 and pv[1] > 0 and pv[2] >0):
                res_row = row
                break
    return res_row

def getEnhancedEdgeImageFromEdgeImage(edge_Image):
    edge_SrcImage = edge_Image
    height, width = edge_SrcImage.shape[0:2]
    for col in range(1, width):
        for row in range(0, height):
            pixel_value = edge_SrcImage[row][col]  # 计算红绿蓝三波段的平均值
            if isPureWhite(pixel_value):
                r_last = getRowNumberSpecificCol(edge_SrcImage, col - 1)
                if r_last:
                    if row > r_last:
                        minR, maxR = r_last, row
                        for k in range(minR, maxR):
                            edge_SrcImage[k][col - 1][0] = 255
                            edge_SrcImage[k][col - 1][1] = 255
                            edge_SrcImage[k][col - 1][2] = 255
                    else:
                        minR, maxR = row, r_last
                        for k in range(minR, maxR):
                            edge_SrcImage[k][col][0] = 255
                            edge_SrcImage[k][col][1] = 255
                            edge_SrcImage[k][col][2] = 255
    # cv2.imshow("Enhanced-edge-image", edge_SrcImage)
    return edge_SrcImage

def getFileExtensionname(filename):
    res = ".png"
    dot_index = -1
    for i in range(len(filename), 0):
        if filename[i] == '.':
            dot_index = i
            break
    if dot_index != -1:
        res = filename[dot_index: len(filename)-1]
    return res

if __name__ == '__main__':
    origin_pic_filename = "D:/test.png"
    sky_ground_threshold = 30
    isDownSampling = False
    if (len(sys.argv) == 1):
        print(sys.argv[0])
        origin_pic_filename = ""
    elif(len(sys.argv) == 2):
        origin_pic_filename = str(sys.argv[1])
    elif(len(sys.argv) == 3):
        origin_pic_filename = str(sys.argv[1])
        sky_ground_threshold = int(sys.argv[2])
    elif (len(sys.argv) == 4):
        origin_pic_filename = str(sys.argv[1])
        sky_ground_threshold = int(sys.argv[2])
        if(int(sys.argv[3]) == 1):
            isDownSampling = True
    if origin_pic_filename != "" and sky_ground_threshold > 0:
        print(("输入图片文件名为:{0}").format(origin_pic_filename))
        print(("天空地面分界灰度阈值为:{0}").format(sky_ground_threshold))
        suffix_name = getFileExtensionname(origin_pic_filename)
        print(("后缀名为:{0}").format(suffix_name))

        srcImage = cv2.imread(origin_pic_filename)
        inputSrcImage = srcImage
        if isDownSampling:
            inputSrcImage = cv2.pyrDown(inputSrcImage)
        height, width = inputSrcImage.shape[0:2]
        print(("高度:{0}, 宽度:{1}").format(height, width))
        cv2.namedWindow('downsampling-image', cv2.WINDOW_AUTOSIZE)
        cv2.imshow("downsampling-image", inputSrcImage)
        Sobelx = cv2.Sobel(inputSrcImage, cv2.CV_64F, 1, 0)
        Sobely = cv2.Sobel(inputSrcImage, cv2.CV_64F, 0, 1)
        Sobelx = cv2.convertScaleAbs(Sobelx)
        Sobely = cv2.convertScaleAbs(Sobely)
        # cv2.imshow("sobel-x-Abs", Sobelx)
        # cv2.imshow("sobel-y-Abs", Sobely)
        Sobelxy = cv2.addWeighted(Sobelx, 0.5, Sobely, 0.5, 0)
        cv2.namedWindow('sobel-xy', cv2.WINDOW_AUTOSIZE)
        cv2.imshow('sobel-xy', Sobelxy)
        edgeImage = getImage(height, width, 3)
        for col in range(0, width):
            for row in range(0, height):
                pixel_value = Sobelxy[row][col]  # 计算红绿蓝三波段的平均值
                if isWhite(pixel_value, sky_ground_threshold):
                    edgeImage[row][col][0] = 255
                    edgeImage[row][col][1] = 255
                    edgeImage[row][col][2] = 255
                    break
        cv2.namedWindow('edge-image', cv2.WINDOW_AUTOSIZE)
        cv2.imshow('edge-image', edgeImage)
        cv2.imwrite(origin_pic_filename.replace(suffix_name, "-ZGetEdge.png"), edgeImage)
        enhanced_edgeImage = getEnhancedEdgeImageFromEdgeImage(edgeImage)
        cv2.namedWindow('enhanced-edge-image', cv2.WINDOW_AUTOSIZE)
        cv2.imshow('enhanced-edge-image', enhanced_edgeImage)
        cv2.imwrite(origin_pic_filename.replace(suffix_name, "-EnhancedEdge.png"), enhanced_edgeImage)

        for col in range(0, width):
            for row in range(0, height):
                pixel_value = enhanced_edgeImage[row][col]  # 计算红绿蓝三波段的平均值
                if isPureWhite(pixel_value):
                    if row+2 < height:
                        inputSrcImage[row+2][col][0] = 0
                        inputSrcImage[row+2][col][1] = 0
                        inputSrcImage[row+2][col][2] = 255
                    else:
                        inputSrcImage[row][col][0] = 0
                        inputSrcImage[row][col][1] = 0
                        inputSrcImage[row][col][2] = 255
                    # inputSrcImage[row][col][0] = 0
                    # inputSrcImage[row][col][1] = 0
                    # inputSrcImage[row][col][2] = 255
                    # break #最开始从每列遍历从上到下找第一个分界点就停止才用break

        cv2.namedWindow('RedEdge-image', cv2.WINDOW_AUTOSIZE)
        cv2.imshow('RedEdge-image', inputSrcImage)
        cv2.imwrite(origin_pic_filename.replace(suffix_name, "-RedEdge.png"), inputSrcImage)
        cv2.waitKey(0)
        cv2.destroyAllWindows()
        print('Success!')
        cv2.waitKey()
        cv2.destroyAllWindows()

3、运行结果

        test.jpg下载

3.1 非下采样+边缘检测

python GetSkyLine.py test.jpg  100
原始图片
边缘点图片
边缘增强图片
sobel-xy处理后图片
downloadsampling图片
红色边缘叠加图片

3.2 下采样+边缘检测

python GetSkyLine.py test.jpg  50  1
原始图片
边缘点图片
边缘增强图片
downloadsampling图片
sobel-xy处理后图片
红色边缘叠加图片

4、小结

        在这个人世间,每个人都是独立的个体,身处浩荡洪流之中,难免身不由己,时而坚定,时而困惑,但我们还是应该永远相信美好的事情终将发生,要心怀一颗感恩的心,相信家人,相信自己,相信未来,坦然面对生活,接受平凡。

       关关难过关关过,前路漫漫亦灿灿

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1425223.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

四、CPU架构介绍和分类

中央处理器&#xff08;central processing unit&#xff0c;简称CPU&#xff09;作为计算机系统的运算和控制核心&#xff0c;是信息处理、程序运行的最终执行单元 1、CPU架构 CPU架构是CPU厂商给属于同一系列的CPU产品定的一个制作规范&#xff0c;主要目的是为了作为区分不同…

最近宣布的NIST后量子密码学标准的3个关键要点

当今世界依赖于许多保护措施&#xff0c;即使您没有注意到这一点。从手机和智能技术到网站&#xff0c;从支付交易到城市基础设施&#xff0c;人们经常与之互动的一切&#xff0c;都通过保护和检查技术来保护。量子计算机能够快速轻松地打破这些保护措施&#xff0c;这是政府和…

Linux, Certbot快速申请免费https证书

linux环境. 更新apt,为了能正确的下载certbot apt update 安装certbot apt install certbot 如果之前nginx已经开启着了,先关掉,防止端口占用 nginx -s stop 运行certbot开始获取证书文件 certbot certonly 输入1直接回车,意思就是让certbot模拟一个web服务器执行下面的…

计算机设计大赛 深度学习 python opencv 实现人脸年龄性别识别

文章目录 0 前言1 项目课题介绍2 关键技术2.1 卷积神经网络2.2 卷积层2.3 池化层2.4 激活函数&#xff1a;2.5 全连接层 3 使用tensorflow中keras模块实现卷积神经网络4 Keras介绍4.1 Keras深度学习模型4.2 Keras中重要的预定义对象4.3 Keras的网络层构造 5 数据集处理训练5.1 …

社交营销巨手:HubSpot的数字推广策略揭密

在数字化的浪潮中&#xff0c;HubSpot作为领先的数字营销平台&#xff0c;一直在积极探索并应用各种关键策略&#xff0c;特别是在主流社交媒体平台上。今天&#xff0c;我们将深入解析HubSpot在数字推广中的关键策略&#xff0c;重点聚焦于其在社交媒体上的运用&#xff0c;以…

python-自动化篇-运维-可视化-绘图库-matplotlib

文章目录 Matplotlibmatplotlib开发环境搭建绘制基础绘制直线绘制折线设置标签文字和线条粗细绘制一元二次方程的曲线yx^2绘制正弦曲线和余弦曲线散点图绘制柱状图绘制饼状图绘制直方图等高线图绘制三维图 Matplotlib Matplotlib 是一个Python的 2D绘图库。通过 Matplotlib&am…

幻兽帕鲁服务器怎么收费?4核16G配置

幻兽帕鲁服务器价格多少钱&#xff1f;4核16G服务器Palworld官方推荐配置&#xff0c;阿里云4核16G服务器32元1个月、96元3个月&#xff0c;腾讯云换手帕服务器服务器4核16G14M带宽66元一个月、277元3个月&#xff0c;8核32G22M配置115元1个月、345元3个月&#xff0c;16核64G3…

redis源码之:redis-cli 集群命令

在集群命令执行前&#xff0c;需要先按上一章节的方式redis源码之&#xff1a;clion搭建cluster环境&#xff0c;启动四个新的redis节点&#xff0c;但不要执行cluster create命令&#xff0c;保持四个节点独立。 redis-cli的命令执行大抵流程差不多&#xff0c;下面以redis-c…

【EI会议征稿中|ACM出版】#先投稿,先送审#第三届网络安全、人工智能与数字经济国际学术会议(CSAIDE 2024)​

#先投稿&#xff0c;先送审#ACM出版#第三届网络安全、人工智能与数字经济国际学术会议&#xff08;CSAIDE 2024&#xff09; 2024 3rd International Conference on Cyber Security, Artificial Intelligence and Digital Economy 2024年3月8日-10日 | 中国济南 会议官网&…

闲人闲谈PS之五十三——离散制造中的魔鬼--物料套裁

惯例闲话&#xff1a;最近和老婆大人商议买车事宜&#xff0c;闲人以为会陷入买油车还是电车的纠结&#xff0c;没想到老婆大人无比坚定&#xff0c;买电车。在买车这方面&#xff0c;老婆的想法居然比闲人超前。闲人对车定位在代步工具&#xff0c;2年前&#xff0c;对车还是印…

【深入浅出SpringCloud原理及实战】「Netflix系列之Hystrix」针对于限流熔断组件Hystrix的回退降级实现方案和机制

针对于限流熔断组件Hystrix的回退降级实现方案和机制 依赖隔离依赖隔离之线程&线程池高延迟请求的例子 线程池的优势线程池的弊端线程池的开销线程池开销 信号量 依赖隔离 Hystrix通过使用『舱壁模式』&#xff08;注&#xff1a;将船的底部划分成一个个的舱室&#xff0c;…

基于单片机温度控制系统的研究

摘 要&#xff1a;笔者基于单片机的温度控制系统&#xff0c;从单片机选择、传感器选择、系统框架设计等方面概述了单片机的温度控制系统内涵&#xff0c;分析了其运行原理&#xff0c;列举了单片机温度控制系统设计的实操方法&#xff0c;从硬件系统、软件系统、温度检测方法…

极简网络邻区自动化操作流程指导手册

一、创建任务 1、策略配置&#xff1a;首先按配置内容进行个性化策略配置 2、任务创建&#xff1a;在专题分析->极简网络分析->极简网络配置任务管理下点击创建任务&#xff0c;具体内容如下填写&#xff1a; 目前策略配置一般配置为城区场景和农村场景&#xff0c;各地…

IS-IS的LSP分片扩展

原理 IS-IS通过泛洪LSP来宣告链路状态信息,由于一个LSP能够承载的信息量有限,IS-IS将对LSP进行分片。每个LSP分片由产生该LSP的结点或伪结点的SystemID、PseudnodeID(普通LSP中该值为0,Pseudonode LSP中该值为非0)、LSPNumber(LSP分片号)组合起来唯一标识,由于LSPNumb…

Google Play上架:因行为透明度被拒审或下架的政策自查(基于区块链的内容)

近期很多朋友的项目出现因行为透明度问题被谷歌拒审或者已经上架的包被下架甚至封号,今天解释一下为什么会被封号下架,根据是什么? 目录 政策发布时间与截止时间政策内容政策背景政策解析和问题讲解政策发布时间与截止时间 基于区块链的内容相关政策,于2023-07-12 公布,…

面向对象设计的七大设计原则

在我们探讨如何创建健壮且可维护的面向对象系统时&#xff0c;有一些原则可以为我们提供指导。这些原则可以帮助我们理解如何最好地组织我们的类和对象&#xff0c;以实现高效、模块化和可扩展的设计。在本篇文章中&#xff0c;我们将探讨这些原则&#xff0c;以及如何在我们的…

前端常见的栈溢出报错

什么是栈溢出&#xff1f; 在前端开发中&#xff0c;栈溢出是指JavaScript引擎执行代码时&#xff0c;调用栈&#xff08;call stack&#xff09;变得太大&#xff0c;超过了浏览器或JavaScript引擎所分配的栈空间&#xff0c;从而导致栈溢出错误。调用栈是一种数据结构&#x…

spring中拦截器Interceptor

目录 什么拦截器&#xff1f; 拦截器的基本使用 注册拦截器中的路径配置 拦截器的执行流程 什么拦截器&#xff1f; 拦截器的基本使用 1.定义拦截器&#xff0c;实现Handlerlnterceptor接口&#xff0c;重写方法 &#xff08;Ctrl 加 o 选择重写的方法&#xff09; Component/…

如何实现任意设备远程SSH访问Deepin操作系统【内网穿透】

文章目录 推荐前言1. 开启SSH服务2. Deppin安装Cpolar3. 配置ssh公网地址4. 公网远程SSH连接5. 固定连接SSH公网地址6. SSH固定地址连接测试 推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击跳…

线性表的链式表示【单链表】

单链表的优缺点 优点缺点 1. 插入和删除操作不需要移动元素&#xff0c;只需要修改指针 2. 不需要大量的连续存储空间 1. 单链表附加指针域&#xff0c;也存在浪费存储空间的缺点。 2. 查找操作需要从表头开始遍历&#xff0c;依次查找&#xff0c;不能随机存取。 单链表结…