SOMS/test/XuAilibTest/SemicircularMeter.cpp
2024-07-15 10:31:26 +08:00

238 lines
7.2 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "SemicircularMeter.h"
#include "DoublePointerAlgorithm.h"
#include <iostream>
#include <SegDetector.h>
#include <NanoDetector.h>
#include <opencv2\imgproc\types_c.h>
#include<opencv2/imgproc/imgproc_c.h>
#include "LineHandle.h"
#include<numeric>
#include<windows.h>
using namespace std;
using namespace cv;
double SemicircularMeter::GetResult(cv::Mat sourceMat,bool IsShowWnd)
{
Mat mat;
sourceMat.copyTo(mat);
if (IsShowWnd) {
imshow("原图", mat);
waitKey(1);
}
int matCols = 400;
Size size;
resize(mat, mat, size, (float)matCols / mat.cols, (float)matCols / mat.cols);
/* if (mat.cols - matCols >0)
{
resize(mat, mat, size, (float)matCols/mat.cols , (float)matCols / mat.cols);
}
else if (mat.cols - matCols < 0)
{
resize(mat, mat, size, (float)matCols /mat.cols , (float)matCols /mat.cols );
}*/
int width = mat.cols;// .width;
int height = mat.rows;
Mat grayMat;
cvtColor(mat, grayMat, COLOR_BGR2GRAY); // 转换为灰度图
//Mat thMat;
adaptiveThreshold(grayMat, grayMat, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 201, 1);
if (IsShowWnd) {
imshow("二值化图adaptiveThreshold", grayMat);
waitKey(1);
}
Mat biMat;
bilateralFilter(grayMat, biMat, 9, 50, 50);
if (IsShowWnd) {
imshow("滤波去噪图", biMat);
waitKey(1);
}
//Mat gaussMat;
GaussianBlur(biMat, grayMat, Size(3, 3), 0, 0);
if (IsShowWnd) {
imshow("高斯模糊图", grayMat);
waitKey(1);
}
medianBlur(grayMat, grayMat, 3);//中值滤波
if (IsShowWnd) {
imshow("中值滤波图", grayMat);
waitKey(1);
}
double t1 = getTickCount();
Mat ROI_1 = Mat(height, width, CV_8UC3, Scalar::all(255));
cvtColor(ROI_1, ROI_1, COLOR_BGR2GRAY); // 转换为灰度图
vector<Mat> vImgs;
Mat result;
vImgs.push_back(grayMat);
vImgs.push_back(ROI_1);
vconcat(vImgs, result); //垂直方向拼接
//hconcat(vImgs, result); //水平方向拼接
if (IsShowWnd)
{
imshow("拼接图", result);
waitKey(1);
}
vector<Vec3f> circles;
Mat whiteMat(height, width, CV_8UC3, Scalar::all(255));
//Mat resizeMat(,)
/* for (size_t i = 0; i < 200; i++)
{
hough_value += i;
HoughCircles(grayMat, circles, HOUGH_GRADIENT, 1, 10, 100, hough_value);
}*/
Mat cannyMat;
Canny(result, cannyMat, 50, 100);//边缘检测
if (IsShowWnd) {
imshow("边缘检测图", cannyMat);
waitKey(1);
}
HoughCircles(cannyMat, circles, HOUGH_GRADIENT, 3, 30, 100,200, 150);
vector<Vec4i> mylines;
//HoughLinesP(grayMat, mylines, 1, CV_PI / 180, 100,5, 1);
//for (size_t i = 0; i < mylines.size(); i++)
//{
// Vec4i cho_l = mylines[i];
// //cho_l
// line(whiteMat, Point(cho_l[0], cho_l[1]), Point(cho_l[2], cho_l[3]), Scalar(255, 0, 0), 1);
//}
vector<Vec3f> rightCircles;
Mat resultCopy;
result.copyTo(resultCopy);
int distance2Center = 40;
for (size_t i = 0; i < circles.size(); i++)
{
if (circles[i][1]>height)
{
if (abs(circles[i][0]-width/2)< distance2Center) //圆心横坐标和纵坐标在拼接后图像中心附近
{
if (abs(circles[i][1] - height) < distance2Center)
{
rightCircles.push_back(circles[i]);
if (IsShowWnd)
{
Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
int radius = cvRound(circles[i][2]);
// circle center
circle(resultCopy, center, 3, Scalar(0, 0, 0), -1, 5, 0);
// circle outline
circle(resultCopy, center, radius, Scalar(0, 0, 0), 3, 3, 0);
}
}
}
}
}
if (IsShowWnd) {
namedWindow("霍夫圆图");
imshow("霍夫圆图", resultCopy);
waitKey(1);
}
adaptiveThreshold(result, result, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 151, 1);
if (IsShowWnd) {
imshow("二次二值化图", result);
waitKey(1);
}
//int w = result.cols;
//int h = result.rows;
//uchar* uc_pixel;
//for (int row = 0; row < h; row++) {
// uc_pixel = result.data + row * result.step;
// for (int col = 0; col < w; col++) {
// //uc_pixel[0];
// //sum += uc_pixel[0];
// uc_pixel[1] = 255;
// uc_pixel[2] = 255;
// uc_pixel[0] = 255;
// uc_pixel += 3;
// }
//}
vector<int> zeroPositions;
vector<pair<int, int>> rightNumSums;
for (size_t j = 0; j < rightCircles.size(); j++)
{
Point ptCenter(cvRound(rightCircles[j][0]), cvRound(rightCircles[j][1]));
int radius = cvRound(rightCircles[j][2]);
Mat darkMatCopy;
result.copyTo(darkMatCopy);
vector<pair<int, int>> num_sum;
//vector<,>
for (size_t i = 300; i < 421; i++)
{
//Point ptStart(ptCenter.x - radius - 10, ptCenter.y);
Point ptStart1(ptCenter.x + sin(i* CV_PI / 180) * (radius + 15), ptCenter.y - cos(i* CV_PI / 180) * (radius + 15));
Point ptStart2(ptCenter.x + sin(i * CV_PI / 180) * (radius - 35), ptCenter.y - cos(i * CV_PI / 180) * (radius - 35));
line(darkMatCopy, ptStart2, ptStart1, Scalar(0, 0, 0), 3);
if (IsShowWnd)
{
imshow("SemicircularMeter", darkMatCopy);
//Sleep(1000);
waitKey(100);
/*string str;
std::cin >> str;*/
}
int matdis = abs( LineHandle::CalcMatSum(darkMatCopy) - LineHandle::CalcMatSum(result)) ;
/* cout << "像素综合darkMatCopy" << i << "" << LineHandle::CalcMatSum(darkMatCopy) << endl;
cout << "像素综合result" << i << "" << LineHandle::CalcMatSum(result) << endl;
cout << "像素综合cha " << i << "" << matdis << endl;*/
num_sum.push_back(make_pair(i, matdis));
if (num_sum.size()>3)
{
if (num_sum[num_sum.size()-3].second - matdis > 20000&& zeroPositions.size() <=j+1)
{
zeroPositions.push_back(i);
}
}
result.copyTo(darkMatCopy);
}
std::sort(num_sum.begin(), num_sum.end(), LineHandle::ComparePairSecond);
if (num_sum.size()>0)
{
rightNumSums.push_back(num_sum[0]);
}
}
std::sort(rightNumSums.begin(), rightNumSums.end(), LineHandle::ComparePairSecond);
if (rightNumSums.size() ==0)
{
return 0.01;
}
std::sort(zeroPositions.begin(), zeroPositions.end());
if (zeroPositions.size() == 0)
{
zeroPositions.push_back( 310);
}
if (zeroPositions[0]>330)
{
zeroPositions[0] = 310;
}
float resutValue = (float)(rightNumSums[0].first - zeroPositions[0]) / 30 + 0.01;
/*if (IsShowWnd) {
imshow("霍夫直线图", whiteMat);
waitKey(1);
}*/
/*if (IsShowWnd) {
waitKey(1000*100);
destroyAllWindows();
}*/
return abs(resutValue);
}