记录并汇总学习和解决问题过程中遇到方法方案
逐步汇总
=== 基础 ===
图像就是矩阵,图像变换就是矩阵变换,关键是得到变换矩阵。
参考这里
opencv得到变换矩阵的几个方法:
points1
, points2
cv2.getAffineTransform(points1,points2)
cv2.getPerspectiveTransform(points1,points2)
=== 例子===
##################### 对图像进行变换(旋转)
import cv2
img = cv2.imread('cat.jpg')
rows,cols,_ = img.shape
#1.得到变换矩阵
#参数 (center),degree, scale
matrix = cv2.getRotationMatrix2D((cols/2,rows/2),90,1)
#2.变换
img1 = cv2.warpAffine(img,matrix,(cols,rows))
cv2.imshow('img',img)
cv2.imshow('img1',img1)
points1
, points2
import numpy as np
#####3个点
points1 = np.float32([[50,50],[200,50],[50,200]])
points2 = np.float32([[10,100],[200,50],[100,250]])
#1.得到变换矩阵
matrix = cv2.getAffineTransform(points1,points2)
#2. 变换
output = cv2.warpAffine(img,matrix,(cols,rows))
#####4个点透视变换
points1 = np.float32([[50,50],[200,50],[50,200],[200,200]])
points2 = np.float32([[10,100],[200,50],[100,250],[150,260])
#1.得到变换矩阵
matrix = cv2.getPerspectiveTransform(points1,points2)
#2. 变换
output = cv2.warpPerspective(img, matrix, (cols, rows))
参考这里
最直接的方法就是直接计算两条直线的交点,然后看看交点是否分别在这两条线段上。这样的方法很容易理解,但是代码实现比较麻烦。
另一种常用的方法是通过向量叉积来判断的,这种方法不需要算出直线方程,在代码实现上比较简便。
用这种方法判别线段是否相交一般分为两步:
struct Line {
double x1;
double y1;
double x2;
double y2;
};
bool intersection(const Line &l1, const Line &l2)
{
//快速排斥实验
if ((l1.x1 > l1.x2 ? l1.x1 : l1.x2) < (l2.x1 < l2.x2 ? l2.x1 : l2.x2) ||
(l1.y1 > l1.y2 ? l1.y1 : l1.y2) < (l2.y1 < l2.y2 ? l2.y1 : l2.y2) ||
(l2.x1 > l2.x2 ? l2.x1 : l2.x2) < (l1.x1 < l1.x2 ? l1.x1 : l1.x2) ||
(l2.y1 > l2.y2 ? l2.y1 : l2.y2) < (l1.y1 < l1.y2 ? l1.y1 : l1.y2))
{
return false;
}
//跨立实验
if ((((l1.x1 - l2.x1)*(l2.y2 - l2.y1) - (l1.y1 - l2.y1)*(l2.x2 - l2.x1))*
((l1.x2 - l2.x1)*(l2.y2 - l2.y1) - (l1.y2 - l2.y1)*(l2.x2 - l2.x1))) > 0 ||
(((l2.x1 - l1.x1)*(l1.y2 - l1.y1) - (l2.y1 - l1.y1)*(l1.x2 - l1.x1))*
((l2.x2 - l1.x1)*(l1.y2 - l1.y1) - (l2.y2 - l1.y1)*(l1.x2 - l1.x1))) > 0)
{
return false;
}
return true;
}
————————————————
版权声明:本文为CSDN博主「Siannodel_」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq826309057/article/details/70942061
参考这里
cv::Mat::Mat()
cv::Mat::Mat(int rows,int cols,int type)
cv::Mat::Mat(Size size,int type )
cv::Mat::Mat(const Mat & m)
cv::Mat a ; //默认构造函数,创建矩阵头
a = cv::imread("test.jpg");//读入图像,矩阵指针指向该像素数据
cv::Mat b = a ;//引用复制
Mat src = imread("test.jpg");
int elem = src.at<int>(0,0);
Mat image2 = image1.clone();//重新复制克隆
image.convertTo(CV_32FC3);
Mat image3;
image1.copyTo(image3);
int cv::Mat::cols
int cv::Mat::rows
uchar* cv::Mat::data // 指向矩阵的数据单元的指针
int cv::Mat::dims // 返回矩阵维度,该维度≥2
MatSize cv::Mat::size // 返回矩阵大小
参考这里
矩形边框(Bounding Rectangle)是说,用一个最小的矩形,把找到的形状包起来。还有一个带旋转的矩形,面积会更小
# 用绿色(0, 255, 0)来画出最小的矩形框架
x, y, w, h = cv2.boundingRect(cnt)
cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)
# 用红色表示有旋转角度的矩形框架
rect = cv2.minAreaRect(cnt)
box = cv2.cv.BoxPoints(rect)
box = np.int0(box)
cv2.drawContours(img, [box], 0, (0, 0, 255), 2)
cv2.imwrite('contours.png', img)
参考这里
from PIL import Image
img = Image.open('examples.png')
img = np.array(img) # 将PIL格式图片转为numpy格式
plt.imshow(Image.open('examples.png')) # 实际上plt.imshow可以直接显示PIL格式图像
cv2.imread()度
import cv2
#已经是np.array了
img = cv2.imread('examples.png') # 默认是读入为彩色图,即使原图是灰度图也会复制成三个相同的通道变成彩色图
plt.imshow(img[..., -1::-1]) # 因为opencv读取进来的是bgr顺序呢的,而imshow需要的是rgb顺序,因此需要先反过来
参考这里
利用感兴趣区域ROI和矩形类Rect
剪裁
cv::Mat src = cv::imread("D:\\OpencvTest\\1.jpg");//原始图像是200*200
cv::Rect rect(-100, -100, 500, 500);
cv::Mat image = src(rect);//这时裁剪,必然出错
————————————————
版权声明:本文为CSDN博主「pan_jinquan」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/guyuealian/article/details/78113325
检查发现越界的话需要填充
OpenCV3中提供了一个图像边界的函数cv::copyMakeBorder(对应opencv2中的cvCopyMakeBorder)以及borderInterpolate
参考这里
'''
获取摄像头的视频流,然后保存到本地,帧率是 20fps,尺寸是 1920x1080.
'''
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('testwrite.avi',fourcc, 20.0, (1920,1080),True)
while(cap.isOpened()):
ret, frame = cap.read()
if ret==True:
cv2.imshow('frame',frame)
out.write(frame)
if cv2.waitKey(10) & 0xFF == ord('q'):
break
else:
break
cap.release()
out.release()
cv2.destroyAllWindows()
参考这里opencv官网linux tutorial安装
# Install minimal prerequisites (Ubuntu 18.04 as reference)
sudo apt update && sudo apt install -y cmake g++ wget unzip
# Download and unpack sources
wget -O opencv.zip https://github.com/opencv/opencv/archive/master.zip
unzip opencv.zip
# Create build directory
mkdir -p build && cd build
# Configure
cmake ../opencv-master
# Build
cmake --build .
sudo make install
pkg-confg的命令和作用参考这里
编译使用opencv的程序时,经常要调用OpenCV一系列库才能成功编译通过,pkg-config经常出现在makefile里用于编译时方便获取opencv必要的一系列库文件位置
下面是opencv,找不到pkg-config时的解决方式,手动添加.pc文件
#注意opencv.pc的路径
cd /usr/local/lib
sudo mkdir pkgconfig
cd pkgconfig
sudo touch opencv.pc
opencv.pc里面添加如下信息
#opencv.pc里面添加如下信息
prefix=/usr/local
exec_prefix=${prefix}
includedir=${prefix}/include
libdir=${exec_prefix}/lib
Name: opencv
Description: The opencv library
Version:4.0.1
Cflags: -I${includedir}/opencv4
Libs: -L${libdir} -lopencv_stitching -lopencv_objdetect -lopencv_calib3d -lopencv_features2d -lopencv_highgui -lopencv_videoio -lopencv_imgcodecs -lopencv_video -lopencv_photo -lopencv_ml -lopencv_imgproc -lopencv_flann -lopencv_core
保存退出后,导入环境变量
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
下面是简洁的opencv makefile的示例
#######
# simple opencv makefile
#######
CXX ?=g++
OPENCV_INCLUDE=/usr/local/include/opencv4 #this is opencv header file path
LDFLAGS += $(shell pkg-config --cflags --libs opencv) #this are dynamic libs for -llib, use pke-config
SRC_CPP=./test_cv.cpp
SRC_EXE=./test
${SRC_EXE}:
${CXX} -o $@ ${SRC_CPP} -I${OPENCV_INCLUDE} ${LDFLAGS}
all: ${SRC_EXE}
clean:
rm -rf ${SRC_EXE}
import cv2
from PIL import Image
import io
import numpy as np
def get_bytesarray(path):
imgbyte=bytearray()
with open(path,'rb') as f:
imgbyte=f.read() #以binary方式读入imgbyte
print('len(imgbyte) ',len(imgbyte))
return imgbyte
def bytesarrayToImg(imgbyte):
nparray=np.frombuffer(imgbyte,np.uint8) #使用np.uint8
print(nparray)
print(nparray.shape)
img = cv2.imdecode(nparray, cv2.COLOR_RGBA2BGR) #cv2的RGB通道是反过来的
print(img.shape)
img=Image.fromarray(img) #进入PIL Image中进行图像操作/显示
img.show()
if __name__=="__main__":
path='./img.jpg'
imgbyte=get_bytesarray(path)
bytesarrayToImg(imgbyte)
这里对文章进行总结:
其他参考材料
超详细的OpenCV入门教程