百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

好!纯python的opencv的照片背景颜色更换探索

bigegpt 2024-09-01 15:22 7 浏览

1 说明:

=====

1.1 对照片进行背景颜色替换,用处比较多。目前用python和opencv来看看。

1.2 纯python和opencv代码来试试看,一起探索和思考,提高自己的思维能力。

参考文章1:

https://blog.csdn.net/weixin_45192980/article/details/107724733?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-7.add_param_isCf&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-7.add_param_isCf

2 bluetored:蓝底变红底

===================

2.1 图片:上图来自今日头条图库:蓝底原图:1111.jpeg

2.2 bluetored.py代码:

import cv2
import numpy as np
#读取蓝底原图
img=cv2.imread('/home/xgj/Desktop/pic-bg/1111.jpeg')
#缩放
rows,cols,channels = img.shape
img=cv2.resize(img,None,fx=0.5,fy=0.5)
rows,cols,channels = img.shape
cv2.imshow('img',img)  #显示蓝底原图
#转换hsv
hsv=cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
lower_blue=np.array([90,70,70])  #提示蓝色底
upper_blue=np.array([110,255,255]) #提示蓝色底
mask = cv2.inRange(hsv, lower_blue, upper_blue)
cv2.imshow('Mask', mask)  #显示mask掩膜图
#腐蚀膨胀
erode=cv2.erode(mask,None,iterations=1)
cv2.imshow('erode',erode)  #显示erode图
dilate=cv2.dilate(erode,None,iterations=1)
cv2.imshow('dilate',dilate)  #显示dilate图
#遍历替换
for i in range(rows):
  for j in range(cols):
    if dilate[i,j]==255:
      img[i,j]=(0,0,255)#此处替换颜色,为BGR通道
cv2.imshow('res',img)  #显示背景颜色为红色的修改后的图片
cv2.waitKey(0)
cv2.destroyAllWindows()

2.3 效果图:

3 whitetored:白底变红底

====================

3.1 图片:来自今日头条图库


3.2 效果图:

3.3 whitetored.py代码:

import cv2
import numpy as np
#白底原图读取
img=cv2.imread('/home/xgj/Desktop/pic-bg/2222.jpeg')
#缩放
rows,cols,channels = img.shape
img=cv2.resize(img,None,fx=0.5,fy=0.5)
rows,cols,channels = img.shape
cv2.imshow('img',img)
#转换hsv
hsv=cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
lower_white = np.array([0, 0, 200])    #白底
upper_white = np.array([180, 40, 255]) #白底
#掩膜
mask = cv2.inRange(hsv, lower_white, upper_white)
cv2.imshow('Mask', mask)
#腐蚀膨胀
erode=cv2.erode(mask,None,iterations=1)
cv2.imshow('erode',erode)
dilate=cv2.dilate(erode,None,iterations=1)
cv2.imshow('dilate',dilate)
#遍历替换
for i in range(rows):
  for j in range(cols):
    if dilate[i,j]==255:
      img[i,j]=(0,0,255)#此处替换颜色,为BGR通道,背景颜色为红底
      #img[i,j]=(255,0,0)  #背景颜色为蓝底,假如白底变蓝底,附加
cv2.imshow('res',img)
cv2.waitKey(0)
cv2.destroyAllWindows()

参考文章2:

https://blog.csdn.net/shenglong456/article/details/71174175?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.add_param_isCf&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.add_param_isCf

4 greentocolor:绿色背景变色

=======================

4.1 图片:来自今日头条图库

4.2 代码:

import cv2
import numpy
#绿色背景照片
img=cv2.imread('/home/xgj/Desktop/pic-bg/mask/ls.jpeg',1)  
# opencv 将BGR 转换成 HSV
imgHSV=cv2.cvtColor(img,cv2.COLOR_BGR2HSV) 
#遍历
for i in range(img.shape[0]):
  for j in range(img.shape[1]):
#判断是否绿色 50和75参数可以改变 应该不是最好
    if imgHSV[i,j,0]<75 and imgHSV[i,j,0]>50:   #难点:判断背景颜色
      #下面是可变背景颜色,附带几种,color
      #img[i,j]=[255,255,255]   #变白色
      #img[i,j]=[0,0,255]   #变红色
      img[i,j]=[255,0,0]   #变蓝色

cv2.namedWindow('Image',cv2.WINDOW_NORMAL)
cv2.imshow('Image',img)
cv2.waitKey(0)
cv2.destoryAllWindows()

4.3 效果图:

===以上都是单一背景颜色的改变===

5 复杂背景的改色或改背景图片:

=========================

5.1 图片:来自今日头条图库

5.2 先抠图,代码如下:交互式抠图

import numpy as np
import cv2
#定义全局变量
n = 0    #定义鼠标按下的次数
ix = 0   # x,y 坐标的临时存储
iy = 0
rect = (0,0,0,0) #前景区域
#鼠标回调函数
def draw_rectangle(event,x,y,flags,param):
    global n,ix,iy,rect
    if event==cv2.EVENT_LBUTTONDOWN :
        if n == 0:    #首次按下保存坐标值
            n+=1
            ix,iy = x,y
        else:        #第二次按下显示矩形
            n+=1
            rect = (ix,iy,(x-ix),(y-iy))#前景区域     
#读取图像
img = cv2.imread('/home/xgj/Desktop/pic-bg/ppp/bw1.jpeg')
mask = np.zeros(img.shape[:2],np.uint8)
bgdModel = np.zeros((1,65),np.float64)
fgdModel = np.zeros((1,65),np.float64)
#选择区域 左上到右下矩形
cv2.namedWindow("img")
cv2.setMouseCallback("img",draw_rectangle)#绑定鼠标
while(n != 2):
    cv2.imshow("img",img)
    cv2.waitKey(2)
#前景提取
cv2.grabCut(img,mask,rect,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_RECT)
mask2 = np.where((mask==2)|(mask==0),0,1).astype('uint8')
img = img*mask2[:,:,np.newaxis]
#显示图像
cv2.imshow("img",img)
#保存,抠图后的图片
cv2.imwrite('/home/xgj/Desktop/pic-bg/ppp/bw2.jpeg',img)
cv2.waitKey()
cv2.destroyAllWindows()

5.3 操作如下图:



5.4 更换背景图片:

=============

5.4.1 参考文章3:

https://blog.csdn.net/haofan_/article/details/76687238

5.4.2 代码:

import cv2
import  numpy as np
#人物图
img=cv2.imread('/home/xgj/Desktop/pic-bg/ppp/bw2.jpeg') 
#需要更改成的背景图片
img_back=cv2.imread('/home/xgj/Desktop/pic-bg/ppp/back.jpeg')
#日常缩放
rows,cols,channels = img_back.shape
img_back=cv2.resize(img_back,None,fx=0.7,fy=0.7)
cv2.imshow('img_back',img_back)
#原人物图片缩放40%
img=cv2.resize(img,None,fx=0.4,fy=0.4)
cv2.imshow('img',img)
rows,cols,channels = img.shape  #rows,cols最后一定要是前景图片的,后面遍历图片需要用到
#转换hsv
hsv=cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
#获取mask
lower_black = np.array([0, 0, 0])
upper_black = np.array([180, 255, 46])
mask = cv2.inRange(hsv, lower_black, upper_black)
cv2.imshow('Mask', mask)
#腐蚀膨胀
erode=cv2.erode(mask,None,iterations=1)
cv2.imshow('erode',erode)
dilate=cv2.dilate(erode,None,iterations=1)
cv2.imshow('dilate',dilate)
#遍历替换
#center=[50,50]#在新背景图片中的位置
center=[int(img.shape[0]/2),50]
for i in range(rows):
    for j in range(cols):
        if dilate[i,j]==0:#0代表黑色的点
            img_back[center[0]+i,center[1]+j]=img[i,j]#此处替换颜色,为BGR通道
cv2.imshow('res',img_back)  #显示效果图
cv2.imwrite('/home/xgj/Desktop/pic-bg/ppp/bw3back.png',img_back)  #保存合成图
cv2.waitKey(0)
cv2.destroyAllWindows()

5.4.3 操作效果图:

===自己整理并分享出来===

喜欢的人,请点赞,关注、评论、转发和收藏。

相关推荐

LangChain4j如何自定义文档转换器实现数据清洗?

LangChain4j提供了3种RAG(Retrieval-AugmentedGeneration,检索增强生成)实现,我们通常在原生或高级的RAG实现中,要对数据进行清洗,也就是将外接...

Java 8 Stream API 详解(java stream.)

Java8StreamAPI详解一、概述在Java8中,StreamAPI是一个重要的新特性。它为处理集合(如List、Set等)中的元素提供了一种高效且富有表现力的方式。Str...

Java修炼终极指南:185 使用 Stream 过滤嵌套集合

这是面试中的一个经典问题,通常从一个模型开始,如下所示(我们假设集合是一个List):publicclassAuthor{privatefinalStringname;pri...

java8的stream使用小示例(java stream())

据JetBrains发布的2021年开发者生态系统调查,Java8在java使用的版本中仍然是当前最流行的版本。72%的专业开发人员使用Java8作为其在java开发中主要编程语言版本。现...

Node.js Stream - 实战篇(node.js in action)

本文转自“美团点评技术团队”http://tech.meituan.com/stream-in-action.html背景前面两篇(基础篇和进阶篇)主要介绍流的基本用法和原理,本篇从应用的角度,介...

Java Stream:集合处理的api(java 集合操作)

JavaStream流:高效集合处理的函数式编程利器一、什么是JavaStream?Java8引入的StreamAPI是一套用于处理集合数据的流式编程接口,通过函数式风格(无副作用的...

去除 List 中的重复元素,你知道几种实现方法?

去除List中重复元素,这在实际编程或面试中经常遇到,每个人都有习惯的写法吧,这里抛砖引玉,汇总了一些实现方案,开拓思路。准备数据假设数组中有10个数据,可能有重复,需要将重复的数据从数组中去掉。pu...

Java开发者必看!Stream流式编程10个爆款技巧,让你代码优雅飞起

为什么你的Java代码总像拧巴的麻绳?掌握这10个Stream实战技巧,代码效率与优雅度将产生质的飞跃。以下案例均来自真实电商系统场景,带你感受流式编程的降维打击!一、过滤与映射组合拳(Filter...

leetcode每日一题之存在重复元素(存在重复元素 iii)

题:给定一个整数数组,判断是否存在重复元素。如果存在一值在数组中出现至少两次,函数返回true。如果数组中每个元素都不相同,则返回false。比如:输入:[1,2,3,1]输出:true...

告别for循环!揭秘Stream API如何让你的代码简洁度提升300%

一、当传统循环遇上现代需求真实场景复现:某电商平台需要处理10万条订单数据,要求:筛选出金额>500的订单提取用户ID并去重统计VIP用户数量传统实现方案://常规写法Set<Long...

Java中List去重的N种方法:从基础到优雅

Java中List去重的N种方法:从基础到优雅在日常的Java开发中,我们经常会遇到需要对List集合去重的情况。无论是为了清理重复的数据,还是为了优化算法性能,掌握多种去重方式都是一项非常实用的技能...

Java Stream流没用过?常用高频方法

概念Stream流是Java8添加的以一种链式调用的方法处理数据,主要侧重于计算。具有以下相关特点代码简洁链式调用Stream常用方法1.将数组变为当作List操作String[]strArr=...

核医学专业名词索引(M-R)(核医学重点归纳)

M吗啡(morphia)埋藏式心律转复除颤器(implantablecardioverterdefibrillator,ICD)麦角骨化醇(VD2,calciferol)脉冲堆积(pulsepi...

CodeMeter 新版发布(codesigner下载)

威步于2022年8月4日发布CodeMeter7.50及CodeMeter软件保护套装11.10,以下为新版内容。CodeMeterRuntime7.50StreamingSIMDExten...

世界上最小的五轴铣床Pocket NC(最小的五轴加工中心)

PocketNC,由MIT学生研制,还有说法是这款产品的设计者是来自美国蒙大拿州的一对极客夫妻。目前主要有两款产品:PocketNCV2-50,9000美元;PocketNCV2-10,60...