计算机视觉
计算机视觉定义
1.人们希望它能够模仿人类的视觉系统
2.作为人工智能的基石
3.从视频、图像中提取信息
主要应用
1.图像分类
2.目标检测
2.目标追踪
3.风格迁移
4.超像素
5.图像拼接
6.语义分割
7.人脸识别
8…
c++ and opencv 下计算机视觉基本实现
1.利用摄像头采集图像并实时对图像中物体进行边缘提取
程序实现:
#include<iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include<opencv2/opencv.hpp>
using namespace cv;
using namespace std;
void trackBar(int, void*);
int s1 = 0, s2 = 0;
Mat src, dst,frame;
int main(){// 读入一张图片(demo)
Mat img = imread("D:\\software\\m\\ConsoleApplication1\\ConsoleApplication1\\1.jpg");// 创建一个名为 "demo"窗口 ?
cvNamedWindow("baby");// 在窗口中显示
//imshow("baby", img);// 等待6000 ms后窗口自动关闭 ?
//waitKey(6000);
//Mat frame;
VideoCapture cap(0);
if (!cap.isOpened()){
cout << "can't open camera\n" << endl;
return 0;
}
while (1)
{
cap >> frame;
imshow("baby", frame);
Canny(frame, dst, 300, 100, 3);
imshow("canny", dst);
//waitKey(60);
if (waitKey(20) > 0)//按下任意键退出摄像头 因电脑环境而异,有的电脑可能会出现一闪而过的情况
break;
}
cap.release();
cv::destroyAllWindows();//关闭所有窗口
}
代码解析:前面半段是利用opencv读取图像并将其显示到界面(显示时间设置为6秒)用于测试。后面利用打开摄像头设备,将摄像头读取图像实时的显示到“baby"窗口中,,然后利用canny对其进行边缘提取并显示,每隔20ms显示窗口刷新依次,如果遇到按下任意按键即可退出。最后关闭摄像头和所有窗口。
2.图像的拼接
代码实现
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/stitching/stitcher.hpp>
using namespace std;
using namespace cv;
bool try_use_gpu = true;
vector<Mat> imgs;
string result_name = "D:\\a\\j.jpg";
int main(int argc, char * argv[])
{
Mat img1 = imread("D:\\a\\z.jpg");
Mat img2 = imread("D:\\a\\x.jpg");
Mat img3 = imread("D:\\a\\q.jpg");
imshow("p1", img1);
imshow("p2", img2);
imshow("p3", img3);
if (img1.empty() || img2.empty())
{
cout << "Can't read image" << endl;
return -1;
}
imgs.push_back(img1);
imgs.push_back(img2);
imgs.push_back(img3);
Stitcher stitcher = Stitcher::createDefault(try_use_gpu);
//使用stitch函数进行拼接
Mat pano;
Stitcher::Status status = stitcher.stitch(imgs, pano);
if (status != Stitcher::OK)
{
cout << "Can't stitch images, error code = " << int(status) << endl;
return -1;
}
imwrite(result_name, pano);
Mat pano2 = pano.clone();
// 显示源图像,和结果图像
imshow("全景图像", pano);
if (waitKey() == 27)
return 0;
}
代码解析:读取所要拼接的图片,将要拼接的图片放入到一个vector容器中,switcher这个类可以实现gpu的加速,并利用switch函数完成图像的拼接,并将其写到定义的文件中。
利用其他算法完成图像的拼接
#include "opencv2/opencv.hpp"
#include <opencv2/core/core.hpp>
#include <opencv2/nonfree/nonfree.hpp>//SIFT
#include <opencv2/legacy/legacy.hpp>//BFMatch暴力匹配
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/stitching/stitcher.hpp>
#include <vector>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
using namespace cv;
void OptimizeSeam(Mat& img1, Mat& trans, Mat& dst);
typedef struct
{
Point2f left_top;
Point2f left_bottom;
Point2f right_top;
Point2f right_bottom;
}four_corners_t;
four_corners_t corners;
void CalcCorners(const Mat& H, const Mat& src)
{
double v2[] = { 0, 0, 1 };//左上角
double v1[3];//变换后的坐标值
Mat V2 = Mat(3, 1, CV_64FC1, v2); //列向量
Mat V1 = Mat(3, 1, CV_64FC1, v1); //列向量
V1 = H * V2;
//左上角(0,0,1)
cout << "V2: " << V2 << endl;
cout << "V1: " << V1 << endl;
corners.left_top.x = v1[0] / v1[2];
corners.left_top.y = v1[1] / v1[2];
//左下角(0,src.rows,1)
v2[0] = 0;
v2[1] = src.rows;
v2[2] = 1;
V2 = Mat(3, 1, CV_64FC1, v2); //列向量
V1 = Mat(3, 1, CV_64FC1, v1); //列向量
V1 = H * V2;
corners.left_bottom.x = v1[0] / v1[2];
corners.left_bottom.y = v1[1] / v1[2];
//右上角(src.cols,0,1)
v2[0] = src.cols;
v2[1] = 0;
v2[2] = 1;
V2 = Mat(3, 1, CV_64FC1, v2); //列向量
V1 = Mat(3, 1, CV_64FC1, v1); //列向量
V1 = H * V2;
corners.right_top.x = v1[0] / v1[2];
corners.right_top.y = v1[1] / v1[2];
//右下角(src.cols,src.rows,1)
v2[0] = src.cols;
v2[1] = src.rows;
v2[2] = 1;
V2 = Mat(3, 1, CV_64FC1, v2); //列向量
V1 = Mat(3, 1, CV_64FC1, v1); //列向量
V1 = H * V2;
corners.right_bottom.x = v1[0] / v1[2];
corners.right_bottom.y = v1[1] / v1[2];
}
void OptimizeSeam(Mat& img1, Mat& trans, Mat& dst)
{
int start = MIN(corners.left_top.x, corners.left_bottom.x);//开始位置,即重叠区域的左边界
double processWidth = img1.cols - start;//重叠区域的宽度
int rows = dst.rows;
int cols = img1.cols; //注意,是列数*通道数
double alpha = 1;//img1中像素的权重
for (int i = 0; i < rows; i++)
{
uchar* p = img1.ptr<uchar>(i); //获取第i行的首地址
uchar* t = trans.ptr<uchar>(i);
uchar* d = dst.ptr<uchar>(i);
for (int j = start; j < cols; j++)
{
//如果遇到图像trans中无像素的黑点,则完全拷贝img1中的数据
if (t[j * 3] == 0 && t[j * 3 + 1] == 0 && t[j * 3 + 2] == 0)
{
alpha = 1;
}
else
{
//img1中像素的权重,与当前处理点距重叠区域左边界的距离成正比,实验证明,这种方法确实好
alpha = (processWidth - (j - start)) / processWidth;
}
d[j * 3] = p[j * 3] * alpha + t[j * 3] * (1 - alpha);
d[j * 3 + 1] = p[j * 3 + 1] * alpha + t[j * 3 + 1] * (1 - alpha);
d[j * 3 + 2] = p[j * 3 + 2] * alpha + t[j * 3 + 2] * (1 - alpha);
}
}
}
int main()
{
Mat srcImg11 = imread("D:\\a\\x.jpg", 1); //Sift surf
Mat srcImg21 = imread("D:\\a\\z.jpg", 1);
//定义SIFT特征检测类对象
Mat srcImg1, srcImg2;
cvtColor(srcImg11, srcImg1, CV_RGB2GRAY);
cvtColor(srcImg21, srcImg2, CV_RGB2GRAY);
SiftFeatureDetector Detector(2000);
vector<KeyPoint> keyPoints1, keyPoints2;
Detector.detect(srcImg1, keyPoints1);
Detector.detect(srcImg2, keyPoints2);
//cout << 2 << endl;
//绘制特征点(关键点)
Mat feature_pic1, feature_pic2;
drawKeypoints(srcImg11, keyPoints1, feature_pic1, Scalar::all(-1));
drawKeypoints(srcImg21, keyPoints2, feature_pic2, Scalar::all(-1));
imshow("p1", feature_pic1);
cout << keyPoints1.size();
//计算特征点描述符 / 特征向量提取
SiftDescriptorExtractor Descriptor;
Mat description1, description2;
Descriptor.compute(srcImg1, keyPoints1, description1);
Descriptor.compute(srcImg2, keyPoints2, description2);
FlannBasedMatcher matcher;
vector<vector<DMatch> > matchePoints;
vector<DMatch> GoodMatchePoints;
vector<Point2f> imagePoints1, imagePoints2;
vector<Mat> train_desc(1, description1);
matcher.add(train_desc);
matcher.train();
matcher.knnMatch(description2, matchePoints, 2);
cout << "total match points: " << matchePoints.size() << endl;
// Lowe's algorithm,获取优秀匹配点
for (int i = 0; i < matchePoints.size(); i++)
{
if (matchePoints[i][0].distance < 0.4 * matchePoints[i][1].distance)
{
GoodMatchePoints.push_back(matchePoints[i][0]);
}
}
cout << GoodMatchePoints.size() << endl;
Mat result;
drawMatches(srcImg21, keyPoints2, srcImg11, keyPoints1, GoodMatchePoints, result, Scalar(0, 255, 0), Scalar::all(-1));//匹配特征点绿色,单一特征点颜色随机
imwrite("romasiftmatchpoints.jpg", result);
imshow("Match_Result", result);
for (int i = 0; i <GoodMatchePoints.size(); i++){
imagePoints2.push_back(keyPoints2[GoodMatchePoints[i].queryIdx].pt);
imagePoints1.push_back(keyPoints1[GoodMatchePoints[i].trainIdx].pt);
}
Mat homo = findHomography(imagePoints1, imagePoints2, CV_RANSAC);
cout << "变换矩阵为:\n" << homo << endl << endl;
CalcCorners(homo, srcImg11);
Mat imageTransform1, imageTransform2;
warpPerspective(srcImg11, imageTransform1, homo, Size(MAX(corners.right_top.x, corners.right_bottom.x), srcImg21.rows));
imshow("直接经过透视矩阵变换", imageTransform1);
int dst_width = imageTransform1.cols; //取最右点的长度为拼接图的长度
int dst_height = srcImg21.rows;
Mat dst(dst_height, dst_width, CV_8UC3);
dst.setTo(0);
imageTransform1.copyTo(dst(Rect(0, 0, imageTransform1.cols, imageTransform1.rows)));
srcImg21.copyTo(dst(Rect(0, 0, srcImg21.cols, srcImg21.rows)));
imshow("final", dst);
imwrite("mmmmmm.jpg", dst);
OptimizeSeam(srcImg21, imageTransform1, dst);
imshow("finalssssssss", dst);
waitKey(600000);
}
代码解析:拼接的依据在于相邻两张图片的特征点,特征点的筛选可以用SIFF,SURF,以及ORB等算法找两张图像的特征点。首先将图片转化为灰度图,然后选取好的特征点,然后计算转换矩阵,然后利用直接透视变换,实现两张图的拼接,拼接后需要将图像融合,去掉缝隙。
3.人脸检测
#include "opencv2/opencv.hpp"
#include <facedetect-dll.h>
using namespace std;
using namespace cv;
//#define DETECT_BUFFER_SIZE 0x20000
int main()
{
int * pResults = NULL;
//在检测函数中使用了pBuffer。
//如果你调用多个线程中的函数,请为每个线程创建一个缓冲区!
unsigned char * pBuffer = (unsigned char *)malloc(0x20000);
if (!pBuffer)
{
fprintf(stderr, "Can not alloc buffer.\n");
return -1;
}
Mat src = imread("m.jpg");
Mat gray;
cvtColor(src, gray, CV_BGR2GRAY);
int doLandmark = 1;// do landmark detection
pResults = facedetect_multiview_reinforce(pBuffer, (unsigned char*)(gray.ptr(0)), gray.cols, gray.rows, (int)gray.step,
1.2f, 2, 48, 0, doLandmark);
//打印检测结果
for (int i = 0; i < (pResults ? *pResults : 0); i++)
{
short * p = ((short*)(pResults + 1)) + 142 * i;
rectangle(src, Rect(p[0], p[1], p[2], p[3]), Scalar(0, 255, 0), 2);
if (doLandmark)
{
for (int j = 0; j < 68; j++)
circle(src, Point((int)p[6 + 2 * j], (int)p[6 + 2 * j + 1]), 1, Scalar(0, 0, 255), 2);
}
}
imshow("Show", src);
imwrite("3d.jpg", src);
waitKey(0);
}
代码解析:将输入的图像或可以利用摄像头采集图像,然后检测人脸,并将其框出。
4.在目标图的指定位置放入某一大小的原图
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
struct userdata{
Mat im;
vector<Point2f> points;
};
void mouseHandler(int event, int x, int y, int flags, void* data_ptr)
{
if (event == EVENT_LBUTTONDOWN)
{
userdata *data = ((userdata *)data_ptr);
circle(data->im, Point(x, y), 3, Scalar(0, 255, 255), 5, CV_AA);
imshow("Image", data->im);
if (data->points.size() < 4)
{
data->points.push_back(Point2f(x, y));
}
}
}
int main(int argc, char** argv)
{
// Read in the image.
Mat im_src = imread("D:\\a\\o.jpg");
Size size = im_src.size();
// Create a vector of points.
vector<Point2f> pts_src;
pts_src.push_back(Point2f(0, 0));
pts_src.push_back(Point2f(size.width - 1, 0));
pts_src.push_back(Point2f(size.width - 1, size.height - 1));
pts_src.push_back(Point2f(0, size.height - 1));
// Destination image
Mat im_dst = imread("D:\\a\\p.jpg");
// Set data for mouse handler
Mat im_temp = im_dst.clone();
userdata data;
data.im = im_temp;
//show the image
imshow("Image", im_temp);
cout << "Click on four corners of a billboard and then press ENTER" << endl;
//set the callback function for any mouse event
setMouseCallback("Image", mouseHandler, &data);
waitKey(0);
// Calculate Homography between source and destination points
Mat h = findHomography(pts_src, data.points);
// Warp source image
warpPerspective(im_src, im_temp, h, im_temp.size());
// Extract four points from mouse data
Point pts_dst[4];
for (int i = 0; i < 4; i++)
{
pts_dst[i] = data.points[i];
}
// Black out polygonal area in destination image.
fillConvexPoly(im_dst, pts_dst, 4, Scalar(0), CV_AA);
imshow("Image1",im_dst);
// Add warped source image to destination image.
im_dst = im_dst + im_temp;
// Display image.
imshow("Image", im_dst);
waitKey(0);
return 0;
}
代码解析:实现利用鼠标,点中目标图的四个点,这四个点的构成的区域由原图来填充到此处。实现的过程包括,点击事件,对应图像的坐标变换,通过投射变换,然后将两者叠起来,就形成变换以后的图。
计算机视觉一些基础以及Opencv使用(python)
1.图像的线性变换与灰度直方图
import cv2
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import pyplot as plt
img = cv2.imread("D:\\software\\m\\ConsoleApplication1\\ConsoleApplication1\\1.jpg",0) # 不加0默认是彩色,否则是灰度
print(img.shape)
cv2.imshow("original",img)
#img1 = np.dot(2,img) +3
img1 = [[]]
plt.hist(img.ravel() , 256, [0, 256])
plt.show()
for i in range(len(img)):
for j in range(len(img[i])):
img[i][j] = img[i][j]*(100)+3; # img[i][j][0]
if(img[i][j]>255):
img[i][j]=255
elif(img[i][j] <= 0):
img[i][j] = 0
cv2.imshow("a",img)
plt.hist(img.ravel() , 256, [0, 256])
plt.show()
print(type(img))
cv2.waitKey(1000000000)
代码解析:实现图像的灰度增强(系数为3 ),增强图像对比度(系数为100)。限定范围防止溢出范围。
2.图像的gama变换
import cv2
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import pyplot as plt
img = cv2.imread("D:\\software\\m\\ConsoleApplication1\\ConsoleApplication1\\1.jpg",0) # 不加0默认是彩色,否则是灰度
print(img.shape)
cv2.imshow("original",img)
#img1 = np.dot(2,img) +3
img1 = [[]]
plt.hist(img.ravel() , 256, [0, 256])
plt.show()
def gamma_trans(img,gamma):
#具体做法先归一化到1,然后gamma作为指数值求出新的像素值再还原
gamma_table = [np.power(x/255.0,gamma)*255.0 for x in range(256)]
gamma_table = np.round(np.array(gamma_table)).astype(np.uint8)
return cv2.LUT(img, gamma_table)
dst = gamma_trans(img,3)
cv2.imshow("a",dst)
plt.hist(dst.ravel() , 256, [0, 256])
plt.show()
print(type(img))
3.图像的灰度阈值变换函数
import cv2
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import pyplot as plt
img = cv2.imread("D:\\software\\m\\ConsoleApplication1\\ConsoleApplication1\\1.jpg",0) # 不加0默认是彩色,否则是灰度
print(img.shape)
cv2.imshow("original",img)
#img1 = np.dot(2,img) +3
img1 = [[]]
plt.hist(img.ravel() , 256, [0, 256])
plt.show()
th1,dst = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
cv2.imshow("a",dst)
plt.hist(dst.ravel() , 256, [0, 256])
plt.show()
print(type(img))
th2 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C,\
cv2.THRESH_BINARY,3,5)
th3 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,\
cv2.THRESH_BINARY,3,5)
cv2.imshow("b",th2)
plt.hist(th2.ravel() , 256, [0, 256])
plt.show()
print(type(img))
cv2.imshow("c",th3)
plt.hist(th3.ravel() , 256, [0, 256])
plt.show()
print(type(img))
cv2.waitKey(1000000000)
#cv2.imwrite
代码解析:分别利用opencv自带的二值化函数,展现了人为设定的阈值以及利用自适应方法设定的阈值进行二值化以后图像处理后的不同结果。
import cv2
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import pyplot as plt
img = cv2.imread("D:\\software\\m\\ConsoleApplication1\\ConsoleApplication1\\1.jpg",0) # 不加0默认是彩色,否则是灰度
print(img.shape)
cv2.imshow("original",img)
#img1 = np.dot(2,img) +3
img1 = [[]]
plt.hist(img.ravel() , 256, [0, 256])
plt.show()
for i in range(len(img)):
for j in range(len(img[i])):
if(img[i][j]<200):
img[i][j] = img[i][j]*0.2; # img[i][j][0]
elif(img[i][j]>=200 and img[i][j]<=220):
img[i][j]= img[i][j]*0.5+3
elif(img[i][j] >220):
img[i][j] = img[i][j]+5
if (img[i][j] > 255):
img[i][j] = 255
elif (img[i][j] <= 0):
img[i][j] = 0
cv2.imshow("a",img)
plt.hist(img.ravel() , 256, [0, 256])
plt.show()
print(type(img))
cv2.waitKey(1000000000)
代码解析:根据阈值,分三段对图像进行不同程度的加强
4.图像的均衡化
import cv2
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import pyplot as plt
img = cv2.imread("D:\\software\\m\\ConsoleApplication1\\ConsoleApplication1\\1.jpg",0) # 不加0默认是彩色,否则是灰度
print(img.shape)
cv2.imshow("original",img)
#img1 = np.dot(2,img) +3
img1 = [[]]
plt.hist(img.ravel() , 256, [0, 256])
plt.show()
dst = cv2.equalizeHist(img)
cv2.imshow("a",dst)
plt.hist(dst.ravel() , 256, [0, 256])
plt.show()
print(type(img))
cv2.waitKey(1000000000)
#cv2.imwrite
直方图均衡化
dst = cv2.equalizeHist(img)
图像的几何变换
1.图像的平移
import cv2
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import pyplot as plt
img = cv2.imread("D:\\software\\m\\ConsoleApplication1\\ConsoleApplication1\\1.jpg") # 不加0默认是彩色,否则是灰度
print(img.shape)
cv2.imshow("original",img)
rows, cols, channel = img.shape
matrix=np.array([[1,0,20],[0,1,20],[0,0,1]],np.float32)
dst=cv2.warpPerspective(img,matrix,(int(cols+500/2),int(rows+500/2)))
cv2.imshow("a",dst)
plt.hist(dst.ravel() , 256, [0, 256])
plt.show()
print(type(img))
rows, cols, channel = img.shape
matrix=np.array([[-1,0,cols],[0,1,0],[0,0,1]],np.float32)
dst1=cv2.warpPerspective(img,matrix,(int(cols+500/2),int(rows+500/2)))
cv2.imshow("b",dst1)
plt.hist(dst1.ravel() , 256, [0, 256])
plt.show()
print(type(img))
rows, cols, channel = img.shape
matrix=np.array([[1,0,0],[0,-1,rows],[0,0,1]],np.float32)
dst2=cv2.warpPerspective(img,matrix,(int(cols+500/2),int(rows+500/2)))
cv2.imshow("c",dst2)
plt.hist(dst2.ravel() , 256, [0, 256])
plt.show()
print(type(img))
cv2.waitKey(1000000000)
#cv2.imwrite
代码解析:注意透视变换里warpPerspective,变换矩阵是右乘坐标矩阵(或图像矩阵)。第一段代码表示向右向下平移20.
第二三段分别表示水平镜像和垂直镜像。
import cv2
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import pyplot as plt
img = cv2.imread("D:\\a\\m.jpg") # 不加0默认是彩色,否则是灰度
print(img.shape)
cv2.imshow("original",img)
#img1 = np.dot(2,img) +3
img1 = [[]]
#plt.hist(img.ravel() , 256, [0, 256])
#plt.show()
rows, cols, channel = img.shape #rows是height cols 是width
centerx=rows*0.5
centery=cols*0.5
x =( np.pi)
a = np.cos(x)
b = np.sin(x)
#c = (np.cos(x))*centerx*(-1)+(np.sin(x))*centery+centerx
#d = -(np.sin(x))*centerx+(np.cos(x))*centery+centery
n1=np.mat([[1,0,0],[0,-1,0],[-centery,centerx,1]],np.float32)
n2=np.mat([[a,-b,0],[b,a,0],[0,0,1]],np.float32)
n3=np.mat([[1,0,0],[0,-1,0],[centery,centerx,1]],np.float32)
n4=np.matmul(n1,n2)
n=np.matmul(n4,n3)
n=n.T
#matrix=np.array([[a,-b,c],[b,a,d],[0,0,1]],np.float32)
dst=cv2.warpPerspective(img,n,(cols,rows))
print(dst.shape)
cv2.imshow("a",dst)
#plt.hist(dst.ravel() , 256, [0, 256])
#plt.show()
print(type(img))
cv2.waitKey(1000000000)
#cv2.imwrite
实现了图像绕任意中心旋转任意角度
代码解析:在python中图像的坐标原点在左上角,向右和向下表示其x,y的正方向。在c++中坐标原点在图像的左下角,向上和向右表示其正方向。注意透视变换里warpPerspective,变换矩阵是右乘坐标矩阵(或图像矩阵)。平移坐标系时左正右负,平移坐标时左负右正。坐标轴反转时乘(-1).一定注意旋转矩阵,平移矩阵坐标轴方向一致再乘
5.图像的插值
最邻近插值,双线性插值
import cv2
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import pyplot as plt
img = cv2.imread("D:\\software\\m\\ConsoleApplication1\\ConsoleApplication1\\1.jpg") # 不加0默认是彩色,否则是灰度
print(img.shape)
cv2.imshow("original",img)
#img1 = np.dot(2,img) +3
#图像插值:INTER_NEAREST最邻近插值,INTER_LINEAR 双线性插值,INTER_AREA 使用像素区域关系进行重采样,INTER_CUBIC 4x4像素邻域的双三次插值,INTER_LANCZOS4 8x8像素邻域的Lanczos插值
rows, cols, channel = img.shape
dst=cv2.resize(img, (int(cols*2),int(rows*2)), interpolation=cv2.INTER_AREA)
cv2.imshow("a",img)
print(type(img))
cv2.waitKey(1000000000)
#cv2.imwrite
6.图像的配准
提取图像的某一目标到另一张图像的指定位置;例如车牌
代码实现:
import cv2
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import pyplot as plt
img = cv2.imread("D:\\a\\m.jpg") # 不加0默认是彩色,否则是灰度
print(img.shape)
cv2.imshow("original",img)
x1 = 108
y1 = 134
x2=156
y2=249
x3=274
y3 =52
x4 =296
y4 =118
points1 = np.float32([[x1,y1],[x2,y2],[x3,y3],[x4,y4]])
points2 = np.float32([[0,0],[0,300],[300,0],[300,300]])
matrix = cv2.getPerspectiveTransform(points1,points2)
dst=cv2.warpPerspective(img,matrix,(300,300))
print(dst.shape)
cv2.imshow("a",dst)
print(type(img))
cv2.waitKey(1000000000)
#cv2.imwrite
代码解析:获取原图中对应车牌四个点对应的像素坐标,设定变换以后的四个点的坐标,利用变换矩阵实现变换,然后经过透视变换就好 。得到车牌正面显示。
7.图像的平滑
1)
import cv2
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import pyplot as plt
img = cv2.imread("D:\\software\\m\\ConsoleApplication1\\ConsoleApplication1\\1.jpg") # 不加0默认是彩色,否则是灰度
print(img.shape)
cv2.imshow("original",img)
#img1 = np.dot(2,img) +3
dst1=cv2.blur(img,(5,5))
dst2=cv2.GaussianBlur(img,(5,5),2)
dst3=cv2.medianBlur(img,5)
cv2.imshow("a",dst1)
cv2.imshow("b",dst2)
cv2.imshow("c",dst3)
print(type(img))
cv2.waitKey(1000000000)
#cv2.imwrite
代码解析:dst1=cv2.blur(img,(5,5)) 平均滤波 块的大小是55
dst2=cv2.GaussianBlur(img,(5,5),2) 高斯平均滤波,块大小55,标准差是2
dst3=cv2.medianBlur(img,5) 中值滤波。块的大小是5
2)加入随机噪声后改进的中值滤波程序
import cv2
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import pyplot as plt
import random
img = cv2.imread("D:\\software\\m\\ConsoleApplication1\\ConsoleApplication1\\1.jpg",0)
img2 =img
print(img.shape)
#print(img)
cv2.imshow("original",img)
huakuai = 7
t = int((huakuai-3)/2 +1)
#图像转化为灰度值在0-1之间
#img2 = cv2.copyMakeBorder(img,1,1,1,1,cv2.BORDER_CONSTANT, value=255)
rows, cols = img2.shape
# 加入噪声
for i in range(rows):
for j in range(cols):
a = random.random()
if(a>0.8):
img2[i][j] = 255
else:
img2[i][j] = img2[i][j]
cv2.imshow("addnoise",img2)
#中值滤波
img3 = cv2.copyMakeBorder(img2,t,t,t,t,cv2.BORDER_CONSTANT, value=255)
img4 = cv2.copyMakeBorder(img2,t,t,t,t,cv2.BORDER_CONSTANT, value=255)
rows, cols = img3.shape
for i in range(rows-huakuai+1):
for j in range(cols-huakuai+1):
if(huakuai == 3):
b = np.array([img3[i][j], img3[i + 1][j], img3[i + 2][j],
img3[i][j + 1], img3[i + 1][j + 1], img3[i + 2][j + 1],
img3[i][j + 2], img3[i + 1][j + 2], img3[i + 2][j + 2]])
if(img3[i+1][j+1] == b.max() or img3[i+1][j+1] == b.min() ):
img4[i+1][j+1]=np.median(b)
elif (huakuai == 5):
b = np.array([img3[i][j] , img3[i + 1][j], img3[i + 2][j], img3[i+3][j], img3[i+4][j],
img3[i][j + 1], img3[i + 1][j + 1], img3[i + 2][j + 1],img3[i + 3][j + 1], img3[i + 4][j + 1],
img3[i][j + 2], img3[i + 1][j + 2], img3[i + 2][j + 2],img3[i + 3][j + 2], img3[i + 4][j + 2],
img3[i][j + 3], img3[i + 1][j + 3], img3[i + 2][j + 3], img3[i + 3][j + 3],img3[i + 4][j + 3],
img3[i][j + 4], img3[i + 1][j + 4], img3[i + 2][j + 4], img3[i + 3][j + 4], img3[i + 4][j + 4]])
if (img3[i + 2][j + 2] == b.max() or img3[i + 2][j + 2] == b.min()):
img4[i + 2][j + 2] = np.median(b)
elif (huakuai == 7):
b = np.array([img3[i][j] , img3[i + 1][j], img3[i + 2][j], img3[i+3][j], img3[i+4][j], img3[i+5][j] , img3[i + 6][j],
img3[i][j + 1], img3[i + 1][j + 1], img3[i + 2][j + 1],img3[i + 3][j + 1], img3[i + 4][j + 1], img3[i+5][j+1] , img3[i + 6][j+1],