使用OpenCV库对图像进行处理,能够实现迷宫寻路的基本功能。通过读取图像、转换为灰度图像、阈值化处理等步骤,我们得到了一个二值化的迷宫图像。然后,我们使用findContours函数找到迷宫的边缘轮廓,并使用drawContours函数将轮廓绘制到图像上。
接下来,我们使用形态学操作对轮廓进行膨胀和腐蚀处理,以平滑边缘并去除噪声。然后,我们计算了膨胀和腐蚀后的图像的绝对差,并将其转换为灰度图像。通过再次调用findContours函数,我们找到了处理后的图像中的轮廓。
这段代码演示了如何使用OpenCV库对图像进行处理,以实现迷宫寻路的功能。通过膨胀、腐蚀和绝对差等形态学操作,我们可以平滑边缘并去除噪声,从而得到更准确的轮廓。这种技术可以应用于许多其他图像处理任务中,例如目标检测、图像分割和特征提取等。
导入库
mport cv2 as cv
import numpy as np
使用OpenCV的imread函数读取位于特定路径的JPEG图像,并将其存储在变量img中。
img = cv.imread(r"C:\Users\RANDALL\Desktop\migong\mi2.jpg")
使用OpenCV的cvtColor函数将彩色图像转换为灰度图像,并将其存储在变量gray中。
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
使用OpenCV的threshold函数对灰度图像进行阈值处理,以产生一个二值化图像。此函数使用Otsu方法进行自动阈值设置。
ret,thresh = cv.threshold(gray,127,255,cv.THRESH_BINARY_INV+cv.THRESH_OTSU)
使用OpenCV的findContours函数查找二值化图像中的轮廓。这里只查找最外面的轮廓,并存储结果在变量contours中
contours,herarchy = cv.findContours(thresh,cv.RETR_EXTERNAL,cv.CHAIN_APPROX_SIMPLE)
创建一个与原始图像大小相同、值全为0的数组,用于后续的图像绘制操作。
draw = np.zeros_like(img)
在上面创建的全黑图像上绘制找到的轮廓,轮廓的颜色为红色(BGR:(255,0,255))。
cv.drawContours(draw,contours,0,(255,0,255),-1)
创建一个19x19大小的矩形结构元素,用于后续的形态学操作。
krenel = cv.getStructuringElement(cv.MORPH_RECT,(19,19))
对上一步绘制的图像进行膨胀操作,使用的是前面创建的结构元素,迭代两次。
dilated = cv.dilate(draw,krenel,iterations=2)
-对膨胀后的图像进行腐蚀操作,使用的是前面创建的结构元素,迭代两次。
eroded = cv.erode(dilated,krenel,iterations=2)
计算膨胀和腐蚀后的图像的绝对差。
diff = cv.absdiff(dilated,eroded)
将绝对差图像从BGR转换为灰度。
diff = cv.cvtColor(diff,cv.COLOR_BGR2GRAY)
在绝对差图像上查找轮廓。
contours2,herarchy2 = cv.findContours(diff,cv.RETR_EXTERNAL,cv.CHAIN_APPROX_SIMPLE)
在原始图像上绘制新找到的轮廓,轮廓的颜色为红色。
cv.drawContours(img,contours2,0,(0,0,255),-1)
显示原始图像(已在上面绘制了新的轮廓)。
cv.imshow('demo',img)
cv.waitKey(0)
cv.destroyAllWindows()
迷宫原图
运行结果在迷宫图上画出了正确路径。
以下是另外一张张迷宫
以下是完整代码示例:
# 导入cv2库,命名别名为cv
import cv2 as cv
# 导入numpy库,命名别名为np
import numpy as np
# 使用cv.imread()函数读取指定路径的图片,并将其保存到变量img中
img = cv.imread(r"C:\Users\RANDALL\Desktop\migong\mi4.jpg")
# 使用cv.cvtColor()函数将img从BGR色彩空间转换为灰度色彩空间,并保存到变量gray中
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
# 使用cv.threshold()函数对灰度图像进行阈值化处理,将像素值高于127的部分设为255,低于127的部分设为0,并保存结果到变量ret和thresh中
ret,thresh = cv.threshold(gray,127,255,cv.THRESH_BINARY_INV+cv.THRESH_OTSU)
# 使用cv.findContours()函数查找二值化图像中的轮廓,并保存结果到变量contours和herarchy中
contours,herarchy = cv.findContours(thresh,cv.RETR_EXTERNAL,cv.CHAIN_APPROX_SIMPLE)
# 创建一个与img大小相同,所有像素值为0的空图像,并保存到变量draw中
draw = np.zeros_like(img)
# 使用cv.drawContours()函数在空图像draw上画出轮廓,轮廓颜色为(255,0,255),即洋红色,轮廓线宽为-1(实线)
cv.drawContours(draw,contours,0,(255,0,255),-1)
# 使用cv.getStructuringElement()函数获取一个形态学结构元素,形状为矩形,大小为(19,19),并保存到变量krenel中
krenel = cv.getStructuringElement(cv.MORPH_RECT,(19,19))
# 使用cv.dilate()函数对图像进行膨胀操作,并保存结果到变量dilated中
dilated = cv.dilate(draw,krenel,iterations=2)
# 使用cv.erode()函数对图像进行腐蚀操作,并保存结果到变量eroded中
eroded = cv.erode(dilated,krenel,iterations=2)
# 使用cv.absdiff()函数计算膨胀和腐蚀后的图像的绝对差,并保存到变量diff中
diff = cv.absdiff(dilated,eroded)
# 使用cv.cvtColor()函数将diff从BGR色彩空间转换为灰度色彩空间,并保存到变量diff中
diff = cv.cvtColor(diff,cv.COLOR_BGR2GRAY)
# 使用cv.findContours()函数查找diff中的轮廓,并保存结果到变量contours2和herarchy2中
contours2,herarchy2 = cv.findContours(diff,cv.RETR_EXTERNAL,cv.CHAIN_APPROX_SIMPLE)
# 使用cv.drawContours()函数在原图img上画出轮廓,轮廓颜色为(0,0,255),即蓝色,轮廓线宽为-1(实线)
cv.drawContours(img,contours2,0,(0,0,255),-1)
# 使用cv.imshow()函数显示处理后的图像,窗口名为'demo'
cv.imshow('demo',img)
# 使用cv.waitKey()函数等待用户按键,该函数的参数为0表示无限等待直到用户按下键盘上的任意键后才继续执行下面的代码
cv.waitKey(0)
希望看完后对你有所帮助,如果喜欢我的文章,麻烦点个小小关注!!!