运用OpenCV进行简单图像处理工作(VS 2015版)
代码内容包括几何投影、游程编码、形态算子、边缘检测和Canny边缘检测。(注:处理后的图像保存在设置的目录下,部分代码不对图像进行显示。)
Image projection部分:
#include"stdafx.h"
#include <iostream>
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
//建立三个函数分别来处理三个投影
void HProjection(Mat mat)
{
Mat hmat;
hmat.create(mat.rows, mat.cols, CV_32F);//存储方式不同
IplImage pmat(mat), phmat(hmat);
//初始化图像的像素值为255
for (int i = 0; i<phmat.height; i++)
{
for (int j = 0; j<phmat.width; j++)
{
cvSetReal2D(&phmat, i, j, 255);
}
}
for (int i = 0; i<pmat.height; i++)
{
int n = phmat.width - 1;
for (int j = 0; j<pmat.width; j++)
{
if (cvGetReal2D(&pmat, i, j) == 0)
{
cvSetReal2D(&phmat, i, n--, 0);
}
}
}
/*Mat rmat(&phmat);
imshow("HPrjection", rmat);
cvWaitKey();*/
//cvSaveImage("D:\\Documents\\Visual Studio 2010\\Projects\\Image projection\\hm.jpg", &phmat);
imwrite("E:\\ckechengxiangmu\\hm1.jpg", hmat);
}
void VProjection(Mat mat)
{
Mat hmat;
hmat.create(mat.rows, mat.cols, CV_32F);//存储方式不同
IplImage pmat(mat), phmat(hmat);
//初始化图像的像素值为255
for (int i = 0; i<phmat.height; i++)
{
for (int j = 0; j<phmat.width; j++)
{
cvSetReal2D(&phmat, i, j, 255);
}
}
for (int i = 0; i<pmat.width; i++)
{
int n = phmat.height - 1;
for (int j = 0; j<pmat.height; j++)
{
if (cvGetReal2D(&pmat, j, i) == 0)
{
cvSetReal2D(&phmat, n--, i, 0);
}
}
}
//Mat rmat(&phmat);
//imshow("VPrjection", rmat);
//cvWaitKey();
//cvSaveImage("D:\\Documents\\Visual Studio 2010\\Projects\\Image projection\\vm.jpg", &phmat);
imwrite("E:\\ckechengxiangmu\\vm1.jpg", hmat);
}
void XProjection(Mat mat)
{
//45度投影比较复杂,代码如下,统计正方形
Mat hmat;
hmat.create(mat.rows, mat.cols, CV_32F);//存储方式不同
IplImage pmat(mat), phmat(hmat);
for (int i = 0; i<phmat.height; i++)
{
for (int j = 0; j<phmat.width; j++)
{
cvSetReal2D(&phmat, i, j, 255);
}
}
for (int i = 0; i<1; i++)
{
for (int j = 0; j<pmat.width; j++)
{
int n = phmat.height - 1;
for (int k = 0; k <= j; k++)
{
if (cvGetReal2D(&pmat, i + k, j - k) == 0)
{
cvSetReal2D(&phmat, n--, j, 0);
}
}
}
}
for (int i = pmat.height - 1; i>pmat.height - 2; i--)
{
for (int j = pmat.width - 1; j>0; j--)
{
int n = phmat.height - 1;
for (int k = 0; k <= pmat.width - 1 - j; k++)
{
if (cvGetReal2D(&pmat, i - k, j + k) == 0)
{
cvSetReal2D(&phmat, n--, j - 1, 0);
}
}
}
}
//Mat rmat(&phmat);
//imshow("XPrjection", rmat);
//cvWaitKey();
//cvSaveImage("D:\\Documents\\Visual Studio 2010\\Projects\\Image projection\\xm.jpg", &phmat);
imwrite("E:\\ckechengxiangmu\\xm1.jpg", hmat);
}
int main()
{
string strpath = "E:\\ckechengxiangmu\\m.jpg";
Mat srcmat = imread(strpath, 0);
//Mat srcmat(cvLoadImage(strpath.c_str(), 0));
Mat ermat;
threshold(srcmat, ermat, 147, 255, CV_THRESH_BINARY);
HProjection(ermat);
VProjection(ermat);
XProjection(ermat);
return 0;
}
RLC部分:
#include"stdafx.h"
#include <iostream>
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
#include <fstream>
int main()
{
//要查找对应的头文件
//64位计算机操作会有差别,本机是64位,可以参考。
string strpath = "E:\\ckechengxiangmu\\m.jpg";
Mat srcmat = imread(strpath, 0);
Mat ermat;
threshold(srcmat, ermat, 147, 255, CV_THRESH_BINARY);
ofstream out;
out.open("E:\\ckechengxiangmu\\m.txt", ios::app);
//在这里最好转成iplimage
IplImage perimage(ermat);
for (int i = 0; i<perimage.height; i++)
{
int count = 1;//作为计数器
out << cvGetReal2D(&perimage, i, 0);//将二值化图像的每一行的第一个值打印出来
for (int j = 0; j<perimage.width - 1; j++)//防止越界
{
if (cvGetReal2D(&perimage, i, j) == cvGetReal2D(&perimage, i, j + 1))
{
count++;
}
else
{
out << count;
count = 1;
}
}
out << endl;
}
out.close();
return 0;
}
EDGETETECTION部分(需要另外添加头文件内容):
//edge.h部分
#pragma once
#include <iostream>
using namespace std;
#include "opencv2/opencv.hpp"
using namespace cv;
class Edgedetection
{
public:
Edgedetection();
public:
~Edgedetection();
public:
Mat Roberts(Mat mat);
Mat Prewitt(Mat mat);
};
//Edgetetecttion部分
#include <iostream>
using namespace std;
#include <opencv2/opencv.hpp>
using namespace cv;
#include "edge.h"
Edgedetection::Edgedetection()
{
}
Edgedetection::~Edgedetection()
{
}
Mat Edgedetection::Roberts(Mat mat)
{
IplImage src(mat), *dst;
dst = cvCloneImage(&src);
int x, y, i, w, h;
int temp, temp1;
uchar* ptr = (uchar*)(dst->imageData);
int ptr1[4] = { 0 };
int indexx[4] = { 0,1,1,0 };
int indexy[4] = { 0,0,1,1 };
w = dst->width;
h = dst->height;
for (y = 0; y < h - 1; y++)
for (x = 0; x < w - 1; x++)
{
for (i = 0; i < 4; i++)
{
ptr1[i] = *(ptr + (y + indexy[i])*dst->widthStep + x + indexx[i]);
}
temp = abs(ptr1[0] - ptr1[2]);
temp1 = abs(ptr1[1] - ptr1[3]);
temp = (temp > temp1 ? temp : temp1);
temp = (int)sqrt(float(temp*temp) + float(temp1*temp1));
*(ptr + y*dst->widthStep + x) = temp;
}
double min_val = 0, max_val = 0;
cvMinMaxLoc(dst, &min_val, &max_val);
int tmp_heigth = dst->height, tmp_width = dst->width;
Mat tmp_mat(CvSize(tmp_width, tmp_heigth), CV_8UC3);
for (int i = 0; i<tmp_heigth; i++)
{
for (int j = 0; j<tmp_width; j++)
{
tmp_mat.at<Vec3b>(i, j)[0] = *((uchar*)(dst->imageData + i*dst->widthStep + (j*dst->nChannels + 0)));
tmp_mat.at<Vec3b>(i, j)[1] = *((uchar*)(dst->imageData + i*dst->widthStep + (j*dst->nChannels + 1)));
tmp_mat.at<Vec3b>(i, j)[2] = *((uchar*)(dst->imageData + i*dst->widthStep + (j*dst->nChannels + 2)));
}
}
//Mat rmat(dst);
Mat rmat = tmp_mat.clone();
return rmat;
};
Mat Edgedetection::Prewitt(Mat mat)
{
IplImage src(mat), *dst;
dst = cvCloneImage(&src);
float prewittx[9] =
{
-1,0,1,
-1,0,1,
-1,0,1
};
float prewitty[9] =
{
1,1,1,
0,0,0,
-1,-1,-1
};
CvMat px;
px = cvMat(3, 3, CV_32F, prewittx);
CvMat py;
py = cvMat(3, 3, CV_32F, prewitty);
IplImage *dstx = cvCreateImage(cvGetSize(&src), 8, 1);
IplImage *dsty = cvCreateImage(cvGetSize(&src), 8, 1);
cvFilter2D(&src, dstx, &px, cvPoint(0,0));
cvFilter2D(&src, dsty, &py, cvPoint(0, 0));
int i, j, temp;
float tempx, tempy;
uchar* ptrx = (uchar*)dstx->imageData;
uchar* ptry = (uchar*)dsty->imageData;
for (i = 0; i < src.width; i++)
{
for (j = 0; j < src.height; j++)
{
tempx = ptrx[i + j*dstx->width];
tempy = ptry[i + j*dsty->width];
temp = (int)sqrt(tempx*tempx + tempy*tempy);
dst->imageData[i + j*dstx->width] = temp;
}
}
int tmp_heigth = dst->height, tmp_width = dst->width;
Mat tmp_mat(CvSize(tmp_width, tmp_heigth), CV_8UC3);
for (int i = 0; i < tmp_heigth; i++)
{
for (int j = 0; j < tmp_width; j++)
{
tmp_mat.at<Vec3b>(i, j)[0] = *((uchar*)(dst->imageData + i*dst->widthStep + (j*dst->nChannels + 0)));
tmp_mat.at<Vec3b>(i, j)[1] = *((uchar*)(dst->imageData + i*dst->widthStep + (j*dst->nChannels + 1)));
tmp_mat.at<Vec3b>(i, j)[2] = *((uchar*)(dst->imageData + i*dst->widthStep + (j*dst->nChannels + 2)));
}
}
//Mat rmat(dst);
Mat rmat = tmp_mat.clone();
//Mat rmat(dst);
return rmat;
}
Edgetetiction部分
#include <iostream>
using namespace std;
#include <opencv2/opencv.hpp>
using namespace cv;
#include "edge.h"
int main()
{
//Roberts边缘检测
String strpath = "E:\\ckechengxiangmu\\aa.jpg";
Mat srcmat = imread(strpath, 0);
Edgedetection e;
Mat Robertsmat = e.Roberts(srcmat);
imshow("Robert", Robertsmat);
cvWaitKey();
IplImage Robertimage(Robertsmat);
cvSaveImage("E:\\ckechengxiangmu\\Robertimage.jpg", &Robertimage);
//Sobel边缘检测
Mat Sobelmat;
Sobel(srcmat, Sobelmat, srcmat.depth(), 1, 1);
imshow("Sobel", Sobelmat);
cvWaitKey();
IplImage Sobelimage(Sobelmat);
cvSaveImage("E:\\ckechengxiangmu\\Sobelimage.jpg", &Sobelimage);
//Prewitt边缘检测
Mat Prewittmat = e.Prewitt(srcmat);
imshow("Prewitt", Prewittmat);
cvWaitKey();
IplImage Prewittimage(Prewittmat);
cvSaveImage("E:\\ckechengxiangmu\\Prewittimage.jpg", &Prewittimage);
//Laplacian边缘不检测
Mat Laplacianmat;
Laplacian(srcmat, Laplacianmat, srcmat.depth());
IplImage Laplacianimage(Laplacianmat);
imshow("Laplacian", Laplacianmat);
cvWaitKey();
cvSaveImage("E:\\ckechengxiangmu\\Laplacianimage.jpg", &Laplacianimage);
//LOG:高斯滤波+Laplacian边缘检测
Mat guassmat;
GaussianBlur(srcmat, guassmat, Size(3, 3), 1);
Mat Logmat;
Laplacian(guassmat, Logmat, guassmat.depth());
imshow("LOG", Logmat);
cvWaitKey();
IplImage Logimage(Logmat);
cvSaveImage("E:\\ckechengxiangmu\\Laplacianimage00.jpg", &Logimage);
return 0;
}
MorphologyOperator部分:
#include "stdafx.h"
#include <iostream>
using namespace std;
#include "opencv2/opencv.hpp"
using namespace cv;
int main()
{
string strpath = "E:\\ckechengxiangmu\\123.jpg";
Mat srcmat(imread(strpath, 0)), erodemat, dilatemat, openmat, closemat;
Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
//首先写腐蚀操作
morphologyEx(srcmat, erodemat, CV_MOP_ERODE, element);
imshow("erode", erodemat);
cvWaitKey();
IplImage erodeimage(erodemat);
cvSaveImage("E:\\ckechengxiangmu\\erodeimage.jpg", &erodeimage);
//膨胀操作
morphologyEx(srcmat, dilatemat, CV_MOP_DILATE, element);
imshow("dilate", dilatemat);
cvWaitKey();
IplImage dilateimage(dilatemat);
cvSaveImage("E:\\ckechengxiangmu\\dilateimage.jpg", &dilateimage);
//开运算
morphologyEx(srcmat, openmat, CV_MOP_OPEN, element);
imshow("open", openmat);
cvWaitKey();
IplImage openimage(openmat);
cvSaveImage("E:\\ckechengxiangmu\\openimage.jpg", &openimage);
//闭运算
morphologyEx(srcmat, closemat, CV_MOP_CLOSE, element);
imshow("close", closemat);
cvWaitKey();
IplImage closeimage(closemat);
cvSaveImage("E:\\ckechengxiangmu\\closeimage.jpg", &closeimage);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理