Python处理图片生成天际线(2024.1.29)
1、天际线简介
天际线(SkyLine
)顾名思义就是天空与地面的边界线,人站在不同的高度,会看到不同的景色和地平线,天空与地面建筑物分离的标记线,不得不说,每天抬头仰望天空,相信大家都可以看到,它的的确确客观存在,美丽值得欣赏。
2、Python代码
#-*- coding:utf-8 -*-
import sys
from os.path import exists
import cv2
import numpy as npdef 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] = 0return imagedef isWhite(pixel_value, threshold): #阈值可以取10、20、30、50、100res = Falseif pixel_value[0] > threshold and pixel_value[1] > threshold and pixel_value[2] > threshold: # 10、10、10 50、50、50 这里是天空和地面楼山的分界线,需要调参res = Truereturn resdef isPureWhite(pixel_value):res = Falseif pixel_value[0] == 255 and pixel_value[1] == 255 and pixel_value[2] == 255: # >3|>3|>3 10、10、10res = Truereturn resdef getRowNumberSpecificCol(image, col):res_row = -1height, 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 = rowbreakreturn res_rowdef getEnhancedEdgeImageFromEdgeImage(edge_Image):edge_SrcImage = edge_Imageheight, 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, rowfor k in range(minR, maxR):edge_SrcImage[k][col - 1][0] = 255edge_SrcImage[k][col - 1][1] = 255edge_SrcImage[k][col - 1][2] = 255else:minR, maxR = row, r_lastfor k in range(minR, maxR):edge_SrcImage[k][col][0] = 255edge_SrcImage[k][col][1] = 255edge_SrcImage[k][col][2] = 255# cv2.imshow("Enhanced-edge-image", edge_SrcImage)return edge_SrcImagedef getFileExtensionname(filename):res = ".png"dot_index = -1for i in range(len(filename), 0):if filename[i] == '.':dot_index = ibreakif dot_index != -1:res = filename[dot_index: len(filename)-1]return resif __name__ == '__main__':origin_pic_filename = "D:/test.png"sky_ground_threshold = 30isDownSampling = Falseif (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 = Trueif 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 = srcImageif 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] = 255edgeImage[row][col][1] = 255edgeImage[row][col][2] = 255breakcv2.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] = 0inputSrcImage[row+2][col][1] = 0inputSrcImage[row+2][col][2] = 255else:inputSrcImage[row][col][0] = 0inputSrcImage[row][col][1] = 0inputSrcImage[row][col][2] = 255# inputSrcImage[row][col][0] = 0# inputSrcImage[row][col][1] = 0# inputSrcImage[row][col][2] = 255# break #最开始从每列遍历从上到下找第一个分界点就停止才用breakcv2.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
![]() | ![]() |
![]() | ![]() |
![]() | ![]() |
3.2 下采样+边缘检测
python GetSkyLine.py test.jpg 50 1

![]() | ![]() |
![]() | ![]() |

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

Python处理图片生成天际线(2024.1.29)
1、天际线简介 天际线(SkyLine)顾名思义就是天空与地面的边界线,人站在不同的高度,会看到不同的景色和地平线,天空与地面建筑物分离的标记线,不得不说,每天抬头仰望天空,相信大家都可…...

jsp服装穿搭推荐系统Myeclipse开发mysql数据库web结构java编程计算机网页项目
一、源码特点 JSP 游戏网上商城系统是一套完善的java web信息管理系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发,数据库为Mysql5.0…...

Opencv(C++)学习 之RV1126平台的OPENCV交叉编译
本文特点:网上已经有了很多opencv移植RV1106的文章,本文主要记录基于cmake-gui编译,碰到的报错,及解决报错问题的方法,同时简单总结一些配置项相关的知识。 一、环境: ubuntu18 x64 RV1126交叉编译工具链 …...
http和https区别
HTTP协议以明文方式发送内容,不提供任何方式的数据加密。HTTP协议不适合传输一些敏感信息,比如:信用卡号、密码等支付信息。https则是具有安全性的ssl加密传输协议。http和https使用的是完全不同的连接方式,用的端口也不一样&…...

富文本编辑器CKEditor4简单使用-05(开发自定义插件入门)
富文本编辑器CKEditor4简单使用-05(开发自定义插件入门) 1. CKEditor4插件入门1.1 关于CKEditor4插件的简单安装与使用1.2 参考 2. 开发自定义插件——当前时间插件2.1 创建插件文件目录结构2.2 编写插件原代码2.2.1 编写代码框架2.2.2 创建编辑器命令2.…...

chisel之scala 语法
Chisel新手教程之Scala语言(1) Value & variable Value是immutable的,当它被分配一个数据后,无法进行重新分配。用 val 表示。 Variable是mutable的,可以重复赋值。用 var 表示。示例如下: val a …...

React18构建Vite+Electron项目以及打包
一.先创建项目 cnpm create vite 选择React > JavaScript >cd react_vite > cnpm i >npm run dev 二.安装Electron依赖 指定版本相对稳定 cnpm i electron19.0.10 -D cnpm i vite-plugin-electron0.9.3 -D cnpm i electron-builder23.0.1 -D三.创建electron目录…...
Spark性能调优
Spark性能调优 executor内存不足用UNION ALL代替UNIONpersist与耗时监控用OR替换UNION ALL用JOIN替换IN executor内存不足 问题表现1:Container xx is running beyond physical memory limits. Current usage: xxx GB of x GB physical memory used; xx GB of x GB…...

flutter开发实战-Camera自定义相机拍照功能实现
flutter开发实战-Camera自定义相机拍照功能实现 一、前言 在项目中使用image_picker插件时候,在android设备上使用无法默认设置前置摄像头(暂时不清楚什么原因),由于项目默认需要使用前置摄像头,所以最终采用自定义…...

LeetCode15. 三数之和
15. 三数之和 给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k ,同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复的三元组。 **注意:**答案中不可以包含重复…...

Docker搭建MySQL8主从复制
之前文章我们了解了面试官:说一说Binlog是怎么实现的,这里我们用Docker搭建主从复制环境。 docker安装主从MySQL 这里我们使用MySQL8.0.32版本: 主库配置 master.cnf //基础配置 [client] port3306 socket/var/run/mysqld/mysql.sock [m…...
【前端】日期转换
记录项目中需要处理的日期格式 默认vue2 初级版 将后端传来的数组 [2024/01/29 08:55:18, 2024/01/29 09:55:18, 2024/01/29 10:11:18]转为 [2024-01-29 08:55, 2024-01-29 09:55, 2024-01-29 10:11]方法 convertDateTimeFormat(arr) {var tempArr arr.map(function (dateT…...

Git 怎么设置用户的权限
在团队协作的软件开发中,对于版本控制系统Git来说,确保代码与数据的安全性至关重要。为了实现这一目标,Git提供了灵活且可定制的用户权限管理机制。下面将简单的探讨一下Git如何设置用户的权限,以及如何保护代码和数据。 用户身份…...
大端和小端模式介绍
介绍 “大端”和“小端”通常指的是字节序(Byte Order)的两种类型,也被称为端序(Endianness)。在多字节的数据类型(如整数)中,字节可以以不同的顺序存储,这影响了计算机…...

【vue】报错 Duplicate keys detected 解决方案
错误描述:Duplicate keys detected. This may cause an update error.错误直译:检测到重复的键。这可能会导致错误。错误原因:有相同父元素的多个子元素的v-for有相同的key值。 解决方法: return:{dataList:[{name:张三…...

机器学习_13_SVM支持向量机、感知器模型
文章目录 1 感知器模型1.1 感知器的思想1.2 感知器模型构建1.3 损失函数构建、求解 2 SVM3 线性可分SVM3.1 线性可分SVM—概念3.2 线性可分SVM —SVM 模型公式表示3.3 线性可分SVM —SVM 损失函数3.4 优化函数求解3.5 线性可分SVM—算法流程3.6 线性可分SVM—案例3.7 线性可分S…...
OpenCV学习记录——轮廓检测
文章目录 前言一、寻找、绘制轮廓二、具体应用代码 前言 寻找目标图像的轮廓并绘制出该轮廓是我们进行图像识别时常用的手段,轮廓是图像中连续的边界线,可以用于物体检测、形状分析等应用。为了获取更高的准确性,会先进行二值化处理ÿ…...
FreeRTOS任务挂起以及延时部分源码分析
layout: post title: “任务状态” date: 2023-7-19 15:39:08 0800 tags: FreeRTOS 任务状态 fireRTOS代码分析 任务挂起 //把一个任务挂起 void vTaskSuspend( TaskHandle_t xTaskToSuspend ) {TCB_t *pxTCB;taskENTER_CRITICAL();//进入临界区{/* 参数是NULL的时候设置为当…...

oracle数据库慢查询SQL
目录 场景: 环境: 慢SQL查询一: 问题一:办件列表查询慢 分析: 解决方法: 问题二:系统性卡顿 分析: 解决方法: 慢SQL查询二 扩展: 场景: 线…...

C语言搭配EasyX实现贪吃蛇小游戏
封面展示 内部展示 完整代码 #define _CRT_SECURE_NO_WARNINGS #include<easyx.h> #include<stdio.h> #include<mmsystem.h> #pragma comment (lib,"winmm.lib") #define width 40//宽有40个格子 #define height 30//长有40个格子 #define size 2…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题
分区配置 (ptab.json) img 属性介绍: img 属性指定分区存放的 image 名称,指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件,则以 proj_name:binary_name 格式指定文件名, proj_name 为工程 名&…...

免费PDF转图片工具
免费PDF转图片工具 一款简单易用的PDF转图片工具,可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件,也不需要在线上传文件,保护您的隐私。 工具截图 主要特点 🚀 快速转换:本地转换,无需等待上…...

Axure 下拉框联动
实现选省、选完省之后选对应省份下的市区...

热烈祝贺埃文科技正式加入可信数据空间发展联盟
2025年4月29日,在福州举办的第八届数字中国建设峰会“可信数据空间分论坛”上,可信数据空间发展联盟正式宣告成立。国家数据局党组书记、局长刘烈宏出席并致辞,强调该联盟是推进全国一体化数据市场建设的关键抓手。 郑州埃文科技有限公司&am…...

路由基础-路由表
本篇将会向读者介绍路由的基本概念。 前言 在一个典型的数据通信网络中,往往存在多个不同的IP网段,数据在不同的IP网段之间交互是需要借助三层设备的,这些设备具备路由能力,能够实现数据的跨网段转发。 路由是数据通信网络中最基…...
C++ 类基础:封装、继承、多态与多线程模板实现
前言 C 是一门强大的面向对象编程语言,而类(Class)作为其核心特性之一,是理解和使用 C 的关键。本文将深入探讨 C 类的基本特性,包括封装、继承和多态,同时讨论类中的权限控制,并展示如何使用类…...
Yii2项目自动向GitLab上报Bug
Yii2 项目自动上报Bug 原理 yii2在程序报错时, 会执行指定action, 通过重写ErrorAction, 实现Bug自动提交至GitLab的issue 步骤 配置SiteController中的actions方法 public function actions(){return [error > [class > app\helpers\web\ErrorAction,],];}重写Error…...