Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 5f29998
Showing
25 changed files
with
346 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# -*- coding: utf-8 -*- | ||
''' | ||
选取ROI区域 | ||
回车或者空格确认选择 | ||
c键 撤销选择 | ||
''' | ||
import numpy as np | ||
import cv2 | ||
import sys | ||
|
||
|
||
# 文件路径 | ||
# img_path = 'blue-color-block.png' | ||
img_path = sys.argv[1] | ||
|
||
# 读入图片 | ||
img = cv2.imread(img_path) | ||
# 创建一个窗口 | ||
cv2.namedWindow("image", flags= cv2.WINDOW_NORMAL | cv2.WINDOW_FREERATIO) | ||
cv2.imshow("image", img) | ||
# 是否显示网格 | ||
showCrosshair = True | ||
|
||
# 如果为Ture的话 , 则鼠标的其实位置就作为了roi的中心 | ||
# False: 从左上角到右下角选中区域 | ||
fromCenter = False | ||
# Select ROI | ||
rect = cv2.selectROI("image", img, showCrosshair, fromCenter) | ||
|
||
print("选中矩形区域") | ||
(x, y, w, h) = rect | ||
|
||
# Crop image | ||
imCrop = img[y : y+h, x:x+w] | ||
|
||
# Display cropped image | ||
cv2.imshow("image_roi", imCrop) | ||
cv2.imwrite("image_roi.png", imCrop) | ||
cv2.waitKey(0) |
Binary file not shown.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
''' | ||
绘制彩图在HSV颜色空间下的统计直方图 | ||
''' | ||
|
||
from matplotlib import pyplot as plt | ||
import numpy as np | ||
import cv2 | ||
import sys | ||
|
||
# 读入图片 | ||
img_path = sys.argv[1] | ||
img = cv2.imread(img_path) | ||
# img = cv2.imread('little_chess.png') | ||
if img is None: | ||
print("图片读入失败, 请检查图片路径及文件名") | ||
exit() | ||
|
||
|
||
# 将图片转换为HSV格式 | ||
img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) | ||
# 创建画布 | ||
fig, ax = plt.subplots() | ||
# Matplotlib预设的颜色字符 | ||
hsvColor = ('y', 'g', 'k') | ||
# 统计窗口间隔 , 设置小了锯齿状较为明显 最小为1 最好可以被256整除 | ||
bin_win = 3 | ||
# 设定统计窗口bins的总数 | ||
bin_num = int(256/bin_win) | ||
# 控制画布的窗口x坐标的稀疏程度. 最密集就设定xticks_win=1 | ||
xticks_win = 2 | ||
# 设置标题 | ||
ax.set_title('HSV Color Space') | ||
lines = [] | ||
for cidx, color in enumerate(hsvColor): | ||
# cidx channel 序号 | ||
# color r / g / b | ||
cHist = cv2.calcHist([img], [cidx], None, [bin_num], [0, 256]) | ||
# 绘制折线图 | ||
line, = ax.plot(cHist, color=color,linewidth=8) | ||
lines.append(line) | ||
|
||
# 标签 | ||
labels = [cname +' Channel' for cname in 'HSV'] | ||
# 添加channel | ||
plt.legend(lines,labels, loc='upper right') | ||
# 设定画布的范围 | ||
ax.set_xlim([0, bin_num]) | ||
# 设定x轴方向标注的位置 | ||
ax.set_xticks(np.arange(0, bin_num, xticks_win)) | ||
# 设定x轴方向标注的内容 | ||
ax.set_xticklabels(list(range(0, 256, bin_win*xticks_win)),rotation=45) | ||
|
||
# 显示画面 | ||
plt.show() |
Binary file not shown.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
# -*- coding: utf-8 -*- | ||
''' | ||
可视化颜色阈值调参软件 | ||
''' | ||
|
||
import cv2 | ||
import numpy as np | ||
import sys | ||
|
||
# 更新MASK图像,并且刷新windows | ||
def updateMask(): | ||
global img | ||
global lowerb | ||
global upperb | ||
global mask | ||
# 计算MASK | ||
mask = cv2.inRange(img_hsv, lowerb, upperb) | ||
|
||
cv2.imshow('mask', mask) | ||
|
||
# 更新阈值 | ||
def updateThreshold(x): | ||
|
||
global lowerb | ||
global upperb | ||
|
||
minH = cv2.getTrackbarPos('minH','image') | ||
maxH = cv2.getTrackbarPos('maxH','image') | ||
minS = cv2.getTrackbarPos('minS','image') | ||
maxS = cv2.getTrackbarPos('maxS', 'image') | ||
minV = cv2.getTrackbarPos('minV', 'image') | ||
maxV = cv2.getTrackbarPos('maxV', 'image') | ||
|
||
lowerb = np.int32([minH, minS, minV]) | ||
upperb = np.int32([maxH, maxS, maxV]) | ||
|
||
print('更新阈值') | ||
print(lowerb) | ||
print(upperb) | ||
updateMask() | ||
|
||
def main(img): | ||
global img_hsv | ||
global upperb | ||
global lowerb | ||
global mask | ||
# 将图片转换为HSV格式 | ||
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) | ||
|
||
# 颜色阈值 Upper | ||
upperb = None | ||
# 颜色阈值 Lower | ||
lowerb = None | ||
|
||
mask = None | ||
|
||
cv2.namedWindow('image', flags= cv2.WINDOW_NORMAL | cv2.WINDOW_FREERATIO) | ||
# cv2.namedWindow('image') | ||
cv2.imshow('image', img) | ||
|
||
# cv2.namedWindow('mask') | ||
cv2.namedWindow('mask', flags= cv2.WINDOW_NORMAL | cv2.WINDOW_FREERATIO) | ||
|
||
# 红色阈值 Bar | ||
## 红色阈值下界 | ||
cv2.createTrackbar('minH','image',0,255,updateThreshold) | ||
## 红色阈值上界 | ||
cv2.createTrackbar('maxH','image',0,255,updateThreshold) | ||
## 设定红色阈值上界滑条的值为255 | ||
cv2.setTrackbarPos('maxH', 'image', 255) | ||
cv2.setTrackbarPos('minH', 'image', 0) | ||
# 绿色阈值 Bar | ||
cv2.createTrackbar('minS','image',0,255,updateThreshold) | ||
cv2.createTrackbar('maxS','image',0,255,updateThreshold) | ||
cv2.setTrackbarPos('maxS', 'image', 255) | ||
cv2.setTrackbarPos('minS', 'image', 0) | ||
# 蓝色阈值 Bar | ||
cv2.createTrackbar('minV','image',0,255,updateThreshold) | ||
cv2.createTrackbar('maxV','image',0,255,updateThreshold) | ||
cv2.setTrackbarPos('maxV', 'image', 255) | ||
cv2.setTrackbarPos('minV', 'image', 0) | ||
|
||
# 首次初始化窗口的色块 | ||
# 后面的更新 都是由getTrackbarPos产生变化而触发 | ||
updateThreshold(None) | ||
|
||
print("调试棋子的颜色阈值, 键盘摁e退出程序") | ||
while cv2.waitKey(0) != ord('e'): | ||
continue | ||
|
||
cv2.imwrite('tmp_bin.png', mask) | ||
cv2.destroyAllWindows() | ||
|
||
if __name__ == "__main__": | ||
# 样例图片 (从命令行中填入) | ||
image_path = sys.argv[1] | ||
# 样例图片 (在代码中填入) | ||
# img = cv2.imread('cfs_samples.jpg') | ||
img = cv2.imread(image_path) | ||
if img is None: | ||
print("Error: 文件路径错误,没有此图片 {}".format(image_path)) | ||
exit(1) | ||
|
||
main(img) |
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
# -*- coding: utf-8 -*- | ||
''' | ||
颜色特征识别 | ||
''' | ||
import numpy as np | ||
import cv2 | ||
|
||
|
||
def color_block_finder(img, lowerb, upperb, | ||
min_w=0, max_w=None, min_h=0, max_h=None): | ||
''' | ||
色块识别 返回矩形信息 | ||
''' | ||
# 转换色彩空间 HSV | ||
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) | ||
# 根据颜色阈值转换为二值化图像 | ||
img_bin = cv2.inRange(img_hsv, lowerb, upperb) | ||
|
||
# 寻找轮廓(只寻找最外侧的色块) | ||
bimg, contours, hier = cv2.findContours(img_bin, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) | ||
# 声明画布 拷贝自img | ||
canvas = np.copy(img) | ||
# 外接矩形区域集合 | ||
rects = [] | ||
|
||
if max_w is None: | ||
# 如果最大宽度没有设定,就设定为图像的宽度 | ||
max_w = img.shape[1] | ||
if max_h is None: | ||
# 如果最大高度没有设定,就设定为图像的高度 | ||
max_h = img.shape[0] | ||
|
||
# 遍历所有的边缘轮廓集合 | ||
for cidx,cnt in enumerate(contours): | ||
# 获取联通域的外界矩形 | ||
(x, y, w, h) = cv2.boundingRect(cnt) | ||
|
||
if w >= min_w and w <= max_w and h >= min_h and h <= max_h: | ||
# 将矩形的信息(tuple)添加到rects中 | ||
rects.append((x, y, w, h)) | ||
return rects | ||
|
||
def draw_color_block_rect(img, rects,color=(0, 0, 255)): | ||
''' | ||
绘制色块的矩形区域 | ||
''' | ||
# 声明画布(canvas) 拷贝自img | ||
canvas = np.copy(img) | ||
# 遍历矩形区域 | ||
for rect in rects: | ||
(x, y, w, h) = rect | ||
# 在画布上绘制矩形区域(红框) | ||
cv2.rectangle(canvas, pt1=(x, y), pt2=(x+w, y+h),color=color, thickness=3) | ||
|
||
return canvas |
Binary file not shown.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
# -*- coding: utf-8 -*- | ||
''' | ||
颜色特征识别测试代码 | ||
''' | ||
import numpy as np | ||
import cv2 | ||
from color_feature import color_block_finder,draw_color_block_rect | ||
|
||
def test_color_block_finder_01(): | ||
''' | ||
色块识别测试样例1 从图片中读取并且识别 | ||
''' | ||
# 图片路径 | ||
img_path = "demo-pic.png" | ||
# 颜色阈值下界(HSV) lower boudnary | ||
lowerb = (96, 210, 85) | ||
# 颜色阈值上界(HSV) upper boundary | ||
upperb = (114, 255, 231) | ||
|
||
# 读入素材图片 BGR | ||
img = cv2.imread(img_path, cv2.IMREAD_COLOR) | ||
# 检查图片是否读取成功 | ||
if img is None: | ||
print("Error: 请检查图片文件路径") | ||
exit(1) | ||
|
||
# 识别色块 获取矩形区域数组 | ||
rects = color_block_finder(img, lowerb, upperb) | ||
# 绘制色块的矩形区域 | ||
canvas = draw_color_block_rect(img, rects) | ||
# 在HighGUI窗口 展示最终结果 | ||
cv2.namedWindow('result', flags=cv2.WINDOW_NORMAL | cv2.WINDOW_FREERATIO) | ||
cv2.imshow('result', canvas) | ||
|
||
# 等待任意按键按下 | ||
cv2.waitKey(0) | ||
# 关闭其他窗口 | ||
cv2.destroyAllWindows() | ||
|
||
def test_color_block_finder_02(): | ||
''' | ||
色块识别测试样例2 从视频流中读取并且识别 | ||
''' | ||
# 视频路径 | ||
video_path = 'demo-video.mkv' | ||
# 颜色阈值下界(HSV) lower boudnary | ||
lowerb = (96, 210, 85) | ||
# 颜色阈值上界(HSV) upper boundary | ||
upperb = (114, 255, 231) | ||
|
||
|
||
# 读入视频流 | ||
cap = cv2.VideoCapture(video_path) | ||
# 色块识别结果展示 | ||
cv2.namedWindow('result', flags=cv2.WINDOW_NORMAL | cv2.WINDOW_FREERATIO) | ||
|
||
while(True): | ||
# 逐帧获取画面 | ||
# ret ? 画面是否获取成功 | ||
ret, frame = cap.read() | ||
|
||
if ret: | ||
img = frame | ||
# 识别色块 获取矩形区域数组 | ||
# 同时设定最小高度还有宽度,过滤噪声 | ||
rects = color_block_finder(img, lowerb, upperb,min_w=10,min_h=10) | ||
# 绘制色块的矩形区域 | ||
canvas = draw_color_block_rect(img, rects) | ||
# 在HighGUI窗口 展示最终结果 更新画面 | ||
cv2.imshow('result', canvas) | ||
|
||
else: | ||
print("视频读取完毕或者视频路径异常") | ||
break | ||
|
||
# 这里做一下适当的延迟,每帧延时0.1s钟 | ||
if cv2.waitKey(50) & 0xFF == ord('q'): | ||
break | ||
|
||
# 释放资源 | ||
cap.release() | ||
cv2.destroyAllWindows() | ||
|
||
|
||
if __name__ == "__main__": | ||
# 测试图片色块识别 | ||
# test_color_block_finder_01() | ||
# 测试视频流色块识别 | ||
test_color_block_finder_02() |
Binary file not shown.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# OpenCV色块识别-例程演示 | ||
|
||
|
Empty file.