什么是ROI:
ROI(region of interest),也就是感兴趣区域,如果你设置了图像了ROI,那么在使用OpenCV的函数的时候,会只对ROI区域操作,其他区域忽略
一、图片切割与合并
原理通过操作图像矩阵来获取或合并指定位置的图像
代码如下:
import cv2 as cv
import numpy as np
src = cv.imread("C:/Users/lenovo/Desktop/opencv/daima/banknum/template-matching-ocr/images/lena.jpg")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
face = src[100:200, 100:200] #高度 宽度
cv.imshow("face", face) #显示截取到的面部
gray = cv.cvtColor(face, cv.COLOR_BGR2GRAY) #把截取到的面部进行灰值处理
cv.imshow("face2", gray) #显示灰值处理后的面部
backface = cv.cvtColor(gray, cv.COLOR_GRAY2BGR) #将灰值的面部转换为BGR格式
cv.imshow("face3", backface)
src[100:200, 100:200] = backface #把已经转换为BGR格式的面部填充到原来的图像中
cv.imshow("face4", src)
print(src.shape)
cv.waitKey(0)
cv.destroyAllWindows() #释放所有的内存
运行截图:
在进行cv.COLOR_GRAY2BGR函数操作时,遇到了一个问题。原以为经过BGR转换后图片会变彩色,但是输出结果还是灰值,这是怎么回事呢?
答:
gray是单通道,还原只能还原为三通道,颜色不变,依旧是灰色。(来源弹幕)
灰度图转为彩色图, 并不知道 RGB 与灰度 的比例关系,只能简单地 设 一点的R=G=B=灰度;
就算转成功了,看上去还是灰色。
或者不想处理图像直接暴力切割与合并,代码如下:
import cv2 as cv
import numpy as np
#截取图片中的指定区域或在指定区域添加某一图片
def jie_image(src1):
src2 = src1[5:89, 500:630]#截取第5行到89行的第500列到630列的区域
cv.imshow("jiequ", src2)
src1[105:189, 300:430] = src2#指定位置填充,大小要一样才能填充
cv.imshow("hecheng", src1)
src = cv.imread("C://1.jpg")
cv.imshow("image", src)
jie_image(src)
cv.waitKey(0)
cv.destroyAllWindows()
怎么判断要截取的头像位置呢?
传送门在此:使用Python实现图像标记点的坐标输出
二、floodFill填充函数
这篇博客写的很棒!ROI和泛洪扩充
2.1 FLOODFILL_FIXED_RANGE填充
代码如下:
import cv2 as cv
import numpy as np
def fill_color_demo(image):
copyImg = image.copy()#复制原图像,不复制原图会修改原图
h, w = image.shape[:2]#读取图像的高和宽
mask = np.zeros([h+2, w+2], np.uint8)#新建图像矩阵 +2是官方函数要求
cv.floodFill(copyImg, mask, (30, 30), (0, 255, 255), (100, 100, 100), (50, 50, 50), cv.FLOODFILL_FIXED_RANGE)#(30, 30)代表起始点;(0, 255, 255)代表填充颜色;loDiff=(100, 100, 100)代表只能填充比填充颜色小对应数值的点,upDiff同理
cv.imshow("fill_color_demo", copyImg)
src = cv.imread("C:/Users/lenovo/Desktop/opencv/daima/banknum/template-matching-ocr/images/lena.jpg")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
fill_color_demo(src)
cv.waitKey(0)
cv.destroyAllWindows() #释放所有的内存
Python+OpenCV图像处理(三)—— Numpy数组操作图片
运行截图:
在学OpenCV的时候遇到个函数floodFill()函数有点不解,特地在这里记录一下。
先说说它的参数
floorFill(image, mask , seedPoint, newVal, loDiff, upDiff, flags)
参数 | 说明 |
---|---|
image | 处理对象 |
mask | 掩膜(后面会说明) |
seedPoint | 填充的起点 |
newVal | 填充的颜色 |
loDiff | 填充时下限像素的差 |
upDiff | 填充时上限像素的差 |
flags | 填充的方式 :FLOODFILL_FIXED_RANGE 和FLOODFILL_MASK_ONLY |
我不懂的地方时填充起始点seedPoint不同,填充位置是怎么看的,下面4张图分别是(30,30)(80,80)(100,100)(150,150)
补充重点:cv2.floodFill(img,mask,seed,newvalue(B,G,R),(loDiff1,loDiff2,loDiff3),(upDiff1,upDiff2,upDiff3),flag)
img:需要处理的图像
mask:一般设置为长宽比img大2的通道为1的数组,其中需要处理的区域设置为0,不需要处理的区域设置为1
seed:起始像素点
newvalue:需要填充的颜色
loDiff和upDiff:需要处理的与seed颜色相近的像素点,即设seed的像素为(B0,G0,R0)。若待处理的像素的值位于(B0-loDiff,G-LoDiff,B-loDiff)到(B0+upDiff,G0+upDiff,R0+upDiff)之间的话就填充newvalue
flag:cv.FLOODFILL_FIXED_RANGE:指定颜色填充
2.2 FLOODFILL_MASK_ONLY 填充
代码如下:
import cv2 as cv
import numpy as np
def fill_binary(image):
image = np.zeros([400, 400, 3], np.uint8) #将所有像素点的各通道数值赋0,全黑
image[100:300, 100:300, :] = 255 #把这个区域的彩色图颜色修改为白色
cv.imshow("fill_binary", image)
mask = np.ones([402, 402, 1], np.uint8) #二值图像mask是单通道,需要指定1。将mask设为1
mask[100:301, 100:301] = 0 #选择白色区域,将填充的区域设为0,和mask相反
cv.floodFill(image, mask, (200, 200), (0, 0, 255), cv.FLOODFILL_MASK_ONLY)
cv.imshow("filled_binary", image)
src = cv.imread("C:/Users/lenovo/Desktop/opencv/daima/banknum/template-matching-ocr/images/lena.jpg")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
fill_binary(src)
cv.waitKey(0)
cv.destroyAllWindows() #释放所有的内存
mask = np.ones([402, 402, 1], np.uint8)#
mask[101:301, 101:301] = 0#
填充的是图像中不为1的点,所以我们需要将需要填充的区域指定为0
(200, 200) 为初始点,我选择的是中心点。
(100, 2, 255):颜色
cv.FLOODFILL_MASK_ONLY:指定位置填充
运行截图:
当时这一步不太懂,为啥要这样写
image[100:300, 100:300, :] = 255 #把这个区域的彩色图颜色修改成黑色
后来看了资料opencv学习笔记3:像素处理,觉得这样写更好
image[100:300, 100:300] = [255, 255, 255]
参考文章:OpenCV 泛洪填充 floodFill()详解
本节视频地址:https://www.bilibili.com/video/BV1QW411F7e7?p=8