opencv测试

简介: opencv测试
#include<iostream>
#include<string.h>
#include<math.h>
#include<vector>
#include<opencv2/core/core.hpp>
#include<opencv2/opencv.hpp>
#include <opencv2/imgproc.hpp>
#include<opencv2/highgui.hpp>
#include "opencv2/ml.hpp"
#include "opencv2/objdetect.hpp"
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2\imgproc\imgproc_c.h>
#include<opencv2\highgui\highgui.hpp>
#include "opencv2/highgui/highgui.hpp"
using namespace std;
using namespace cv;
void swap(int& x, int& y)
{
 int temp;
 temp = x;
 x = y;
 y = temp;
}
// 去噪匹配
int searchmedia(int *arr, int length)
{
 int i, j;
 for (i = 0; i < length - 1; i++)
     for (j = 0; j < length - i - 1; j++)
     {
         if (arr[j] > arr[j + 1])
             swap(arr[j], arr[j + 1]);
     }
 return arr[4];
}
// 中值滤波去噪处理
void MediaFilter(Mat& Saltimg, Mat& _dst)
{
 Mat dst = Mat(Saltimg.size(), Saltimg.type());
 int arr[9];
 // channels()返回矩阵通道的数量。
 if (dst.channels() == 3)
 {
     for (int i = 0; i < dst.rows; i++)
         for (int j = 0; j < dst.cols; j++)
         {
             if (i - 1 > 0 && j - 1 > 0 && i < dst.rows - 1 && j < dst.cols - 1)
             {
                 arr[0] = Saltimg.at<Vec3b>(i - 1, j - 1)[0];
                 arr[1] = Saltimg.at<Vec3b>(i - 1, j)[0];
                 arr[2] = Saltimg.at<Vec3b>(i - 1, j + 1)[0];
                 arr[3] = Saltimg.at<Vec3b>(i, j - 1)[0];
                 arr[4] = Saltimg.at<Vec3b>(i, j)[0];
                 arr[5] = Saltimg.at<Vec3b>(i, j + 1)[0];
                 arr[6] = Saltimg.at<Vec3b>(i + 1, j - 1)[0];
                 arr[7] = Saltimg.at<Vec3b>(i + 1, j)[0];
                 arr[8] = Saltimg.at<Vec3b>(i + 1, j + 1)[0];
                 dst.at<Vec3b>(i, j)[0] = searchmedia(arr, 9);
                 arr[0] = Saltimg.at<Vec3b>(i - 1, j - 1)[1];
                 arr[1] = Saltimg.at<Vec3b>(i - 1, j)[1];
                 arr[2] = Saltimg.at<Vec3b>(i - 1, j + 1)[1];
                 arr[3] = Saltimg.at<Vec3b>(i, j - 1)[1];
                 arr[4] = Saltimg.at<Vec3b>(i, j)[1];
                 arr[5] = Saltimg.at<Vec3b>(i, j + 1)[1];
                 arr[6] = Saltimg.at<Vec3b>(i + 1, j - 1)[1];
                 arr[7] = Saltimg.at<Vec3b>(i + 1, j)[1];
                 arr[8] = Saltimg.at<Vec3b>(i + 1, j + 1)[1];
                 dst.at<Vec3b>(i, j)[1] = searchmedia(arr, 9);
                 arr[0] = Saltimg.at<Vec3b>(i - 1, j - 1)[2];
                 arr[1] = Saltimg.at<Vec3b>(i - 1, j)[2];
                 arr[2] = Saltimg.at<Vec3b>(i - 1, j + 1)[2];
                 arr[3] = Saltimg.at<Vec3b>(i, j - 1)[2];
                 arr[4] = Saltimg.at<Vec3b>(i, j)[2];
                 arr[5] = Saltimg.at<Vec3b>(i, j + 1)[2];
                 arr[6] = Saltimg.at<Vec3b>(i + 1, j - 1)[2];
                 arr[7] = Saltimg.at<Vec3b>(i + 1, j)[2];
                 arr[8] = Saltimg.at<Vec3b>(i + 1, j + 1)[2];
                 dst.at<Vec3b>(i, j)[2] = searchmedia(arr, 9);
             }
             else
             {
                 dst.at<Vec3b>(i, j)[0] = Saltimg.at<Vec3b>(i, j)[0];
                 dst.at<Vec3b>(i, j)[1] = Saltimg.at<Vec3b>(i, j)[1];
                 dst.at<Vec3b>(i, j)[2] = Saltimg.at<Vec3b>(i, j)[2];
             }
         }
 }
 else if (dst.channels() == 1)
 {
     for (int i = 0; i < dst.rows; i++)
         for (int j = 0; j < dst.cols; j++)
         {
             if (i - 1 > 0 && j - 1 > 0 && i < dst.rows - 1 && j < dst.cols - 1)
             {
                 arr[0] = Saltimg.at<uchar>(i - 1, j - 1);
                 arr[1] = Saltimg.at<uchar>(i - 1, j);
                 arr[2] = Saltimg.at<uchar>(i - 1, j + 1);
                 arr[3] = Saltimg.at<uchar>(i, j - 1);
                 arr[4] = Saltimg.at<uchar>(i, j);
                 arr[5] = Saltimg.at<uchar>(i, j + 1);
                 arr[6] = Saltimg.at<uchar>(i + 1, j - 1);
                 arr[7] = Saltimg.at<uchar>(i + 1, j);
                 arr[8] = Saltimg.at<uchar>(i + 1, j + 1);
                 dst.at<uchar>(i, j) = searchmedia(arr, 9);
             }
             else
             {
                 dst.at<uchar>(i, j) = Saltimg.at<uchar>(i, j);
             }
         }
 }
 dst.copyTo(_dst);
}
int gray[256] = { 0 };  //记录每个灰度级别下的像素个数
double gray_prob[256] = { 0 };  //记录灰度分布密度
double gray_distribution[256] = { 0 };  //记录累计密度
int gray_equal[256] = { 0 };  //均衡化后的灰度值
int gray_sum = 0;  //像素总数
Mat equalize_hist(Mat& input)
{
 Mat output = input.clone();
 gray_sum = input.cols * input.rows;
 //统计每个灰度下的像素个数
 for (int i = 0; i < input.rows; i++)
 {
     uchar* p = input.ptr<uchar>(i);
     for (int j = 0; j < input.cols; j++)
     {
         int vaule = p[j];
         gray[vaule]++;
     }
 }
 //统计灰度频率
 for (int i = 0; i < 256; i++)
 {
     gray_prob[i] = ((double)gray[i] / gray_sum);
 }
 //计算累计密度
 gray_distribution[0] = gray_prob[0];
 for (int i = 1; i < 256; i++)
 {
     gray_distribution[i] = gray_distribution[i - 1] + gray_prob[i];
 }
 //重新计算均衡化后的灰度值,四舍五入。参考公式:(N-1)*T+0.5
 for (int i = 0; i < 256; i++)
 {
     gray_equal[i] = (uchar)(255 * gray_distribution[i] + 0.5);
 }
 //直方图均衡化,更新原图每个点的像素值
 for (int i = 0; i < output.rows; i++)
 {
     uchar* p = output.ptr<uchar>(i);
     for (int j = 0; j < output.cols; j++)
     {
         p[j] = gray_equal[p[j]];
     }
 }
 return output;
}
// 画直方图
void drawHist(Mat& img)
{
 //为计算直方图配置变量  
 //首先是需要计算的图像的通道,就是需要计算图像的哪个通道(bgr空间需要确定计算 b或g货r空间)  
 int channels = 0;
 //然后是配置输出的结果存储的 空间 ,用MatND类型来存储结果  
 MatND dstHist;
 //接下来是直方图的每一个维度的 柱条的数目(就是将数值分组,共有多少组)  
 int histSize[] = { 256 };       //如果这里写成int histSize = 256;   那么下面调用计算直方图的函数的时候,该变量需要写 &histSize  
 //最后是确定每个维度的取值范围,就是横坐标的总数  
 //首先得定义一个变量用来存储 单个维度的 数值的取值范围  
 float midRanges[] = { 0, 256 };
 const float *ranges[] = { midRanges };
 calcHist(&img, 1, &channels, Mat(), dstHist, 1, histSize, ranges, true, false);
 //calcHist  函数调用结束后,dstHist变量中将储存了 直方图的信息  用dstHist的模版函数 at<Type>(i)得到第i个柱条的值  
 //at<Type>(i, j)得到第i个并且第j个柱条的值  
 //开始直观的显示直方图——绘制直方图  
 //首先先创建一个黑底的图像,为了可以显示彩色,所以该绘制图像是一个8位的3通道图像  
 Mat drawImage = Mat::zeros(Size(256, 256), CV_8UC3);
 //因为任何一个图像的某个像素的总个数,都有可能会有很多,会超出所定义的图像的尺寸,针对这种情况,先对个数进行范围的限制  
 //先用 minMaxLoc函数来得到计算直方图后的像素的最大个数  
 double g_dHistMaxValue;
 minMaxLoc(dstHist, 0, &g_dHistMaxValue, 0, 0);
 //将像素的个数整合到 图像的最大范围内  
 //遍历直方图得到的数据  
 for (int i = 0; i < 256; i++)
 {
     int value = cvRound(dstHist.at<float>(i) * 256 * 0.9 / g_dHistMaxValue);
     line(drawImage, Point(i, drawImage.rows - 1), Point(i, drawImage.rows - 1 - value), Scalar(255, 255, 255));
 }
 namedWindow("直方图",WINDOW_AUTOSIZE);
 imshow("直方图", drawImage);
}
int DetectThreshold(Mat *src)
{
 uchar iThrehold;//阀值
 try
 {
     int height = src->cols; 
     int width = src->rows;
     int step = src->rows / sizeof(uchar);
     uchar *data = src->data;
     cout << src->cols << endl
         << src->rows<<endl;
     int iDiffRec = 0;
     int F[256] = { 0 }; //直方图数组  
     int iTotalGray = 0;//灰度值和  
     int iTotalPixel = 0;//像素数和  
     uchar bt;//某点的像素值  
     uchar iNewThrehold;//新阀值
     uchar iMaxGrayValue = 0, iMinGrayValue = 255;//原图像中的最大灰度值和最小灰度值  
     uchar iMeanGrayValue1, iMeanGrayValue2;
     //获取(i,j)的值,存于直方图数组F  
     for (int i = 0; i < width; i++)
     {
         for (int j = 0; j < height; j++)
         {
             bt = data[i*step + j];
             if (bt < iMinGrayValue)
                 iMinGrayValue = bt;
             if (bt > iMaxGrayValue)
                 iMaxGrayValue = bt;
             F[bt]++;
         }
     }
     iThrehold = 0;
     iNewThrehold = (iMinGrayValue + iMaxGrayValue) / 2;//初始阀值  
     iDiffRec = iMaxGrayValue - iMinGrayValue;
     for (int a = 0; (abs(iThrehold - iNewThrehold) > 0.5); a++)//迭代中止条件  
     {
         iThrehold = iNewThrehold;
         //小于当前阀值部分的平均灰度值  
         for (int i = iMinGrayValue; i < iThrehold; i++)
         {
             iTotalGray += F[i] * i;//F[]存储图像信息  
             iTotalPixel += F[i];
         }
         iMeanGrayValue1 = (uchar)(iTotalGray / iTotalPixel);
         //大于当前阀值部分的平均灰度值  
         iTotalPixel = 0;
         iTotalGray = 0;
         for (int j = iThrehold + 1; j < iMaxGrayValue; j++)
         {
             iTotalGray += F[j] * j;//F[]存储图像信息  
             iTotalPixel += F[j];
         }
         iMeanGrayValue2 = (uchar)(iTotalGray / iTotalPixel);
         iNewThrehold = (iMeanGrayValue2 + iMeanGrayValue1) / 2; //新阀值  
         iDiffRec = abs(iMeanGrayValue2 - iMeanGrayValue1);
     }
 }
 catch (cv::Exception e)
 {
 }
 return iThrehold;
}
//度数转换
double degreeTurn(double theta)
{
 double finaldegree = theta / CV_PI * 180;
 return finaldegree;
}
//逆时针旋转图像degree角度(原尺寸) 
void rotateImage(Mat Img, Mat& rotateImg, double degree)
{
 //旋转中心为图像中心 
 Point2f center;
 center.x = float(Img.cols / 2.0);
 center.y = float(Img.rows / 2.0);
 int length = 0;
 length = sqrt(Img.cols * Img.cols + Img.rows * Img.rows);
 Mat matrix = getRotationMatrix2D(center, degree, 1);//仿射变换矩阵
 warpAffine(Img, rotateImg, matrix, Size(length, length), 1, 0, Scalar(255, 255, 255));//原大小进行仿射变换
}
//通过霍夫变换计算角度
double CalcDegree(const Mat& srcImage)
{
 Mat midImage;
 Sobel(srcImage, midImage, -1, 0, 1, 5);
 //通过霍夫变换检测直线
 vector<Vec2f> lines;
 HoughLines(midImage, lines, 1, CV_PI / 180, 300, 0, 0);//阈值越大,精度越高
 //根据阈值由大到小设置了三个阈值,如果经过大量试验后,可以固定一个适合的阈值。
 if (!lines.size())
 {
     HoughLines(midImage, lines, 1, CV_PI / 180, 200, 0, 0);
 }
 if (!lines.size())
 {
     HoughLines(midImage, lines, 1, CV_PI / 180, 150, 0, 0);
 }
 float all_t = 0;
 for (size_t i = 0; i < lines.size(); i++)
 {
     float theta = lines[i][1];//选择角度最小的角作为旋转角
     //计算所有角度
     all_t += theta;
 }
 float average = all_t / lines.size(); //对所有角度求平均
 double degree = degreeTurn(average) - 90;
 return degree;
}
int main()
{
 // 存放所有路径名
 vector<string> m_item;
 //string m_pathname="D:\\Study\\temp\\image\\*.jpg";
 string m_pathname = "image\\*.jpg";
 glob(m_pathname, m_item);
 /*
 路径测试
 vector<string>::iterator it;
 for (it=m_item.begin();it!= m_item.end() ; it++)
 {
     cout << *it << endl;
 }*/
 // 处理每一个图片
 for (int i = 0; i < m_item.size(); ++i)
 {
     Mat src = imread(m_item[i]);
     if (src.empty())
     {
         cout << "加载图片 :" << m_item[i] << " 失败!" << endl;
         continue;
     }
     Mat gray_dst, result_dst;
     cvtColor(src, gray_dst, COLOR_BGR2GRAY);
     // 去噪处理
     MediaFilter(gray_dst, result_dst);
     /*
         去噪处理后 图片显示测试代码
     */
     namedWindow("原图", WINDOW_NORMAL);
     imshow("原图", src);
     namedWindow("灰度图", WINDOW_NORMAL);
     imshow("灰度图", gray_dst);
     // 去噪处理
     MediaFilter(gray_dst, result_dst);
     namedWindow("中值滤波去噪后", WINDOW_NORMAL);
     imshow("中值滤波去噪后", result_dst);
     //cout << "处理图片 :" << m_item[i] << " 成功!" << endl;
     // 灰度直方图
     //int nRows = 600, nCols = 800;
     //Mat g_dstImg(nRows, nCols, CV_8UC1, Scalar::all(0)); // 新建画布
     //namedWindow("g_dstImg", WINDOW_AUTOSIZE);
     //imshow("g_dstImg", g_dstImg);
     //Mat histImg = equalize_hist(result_dst);
     // namedWindow("均值化图", WINDOW_NORMAL);
     //imshow("均值化图", histImg);
     // drawHist(result_dst);
     drawHist(result_dst);
     // adaptiveThreshold(result_dst, temp, 255,ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY,21,10);
     //namedWindow("原图", WINDOW_NORMAL);
     //imshow("原图", histImg);
     Mat *decect=new Mat(result_dst);
     int dec=DetectThreshold(decect);
     cout << dec << endl;
     Mat binaryImg;
     threshold(result_dst, binaryImg, dec, 255, CV_THRESH_BINARY);
     namedWindow("二值图", WINDOW_NORMAL);
     imshow("二值图", binaryImg);
     //Mat angleImg;
     //angleCount(result_dst,angleImg);
     //namedWindow("角度图", WINDOW_NORMAL);
     //imshow("角度图", angleImg);
     // 输出二值图片
     //string strnn;
     //strnn += ".\\new\\";
     //strnn += m_item[i];
     //strnn += +".jpg";
     //cout << strnn << endl;
     //imwrite(strnn, binaryImg);
     waitKey(0);
 }
 waitKey(0);
 return 0;
}
相关文章
|
XML 机器学习/深度学习 存储
基于OpenCV训练口罩检测数据集并测试
基于OpenCV训练口罩检测数据集并测试
316 0
基于OpenCV训练口罩检测数据集并测试
|
Web App开发 测试技术 应用服务中间件
|
Ubuntu 测试技术 Android开发
36.FFmpeg+OpenCV直播推流(搭建crtmpserver服务器并使用ffmepg,vlc测试推流播放)
开发环境 Ubuntu 16 64位+Windows10 开发过程 1.登录Ubuntu切换到root用户(减少权限问题),执行以下命令 apt update 它的作用是同步 /etc/apt/sources.list 和 /etc/apt/sources.list.d 中列出的源的索引,这样才能获取到最新的软件包。
3954 0
|
13天前
|
计算机视觉 Python
轻松掌握opencv的8种图像变换
轻松掌握opencv的8种图像变换
|
15天前
|
算法 计算机视觉
【OpenCV】- 图像修复
【OpenCV】- 图像修复
|
15天前
|
Serverless 计算机视觉
【OpenCV】-图像的矩
【OpenCV】-图像的矩
|
15天前
|
编解码 物联网 计算机视觉
【OpenCV】—图像金子塔与图片尺寸缩放
【OpenCV】—图像金子塔与图片尺寸缩放
|
15天前
|
前端开发 计算机视觉 C++
【OpenCV】—分离颜色通道、多通道图像混合
【OpenCV】—分离颜色通道、多通道图像混合
|
15天前
|
API 计算机视觉
【OpenCV】—图像对比度、亮度值调整
【OpenCV】—图像对比度、亮度值调整
|
15天前
|
计算机视觉 索引
【OpenCV】—ROI区域图像叠加&图像混合
【OpenCV】—ROI区域图像叠加&图像混合