BaseFunction.cpp 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. #include "stdafx.h"
  2. #include "BaseFunction.h"
  3. #include <opencv2/core/core.hpp>
  4. #include <opencv2/highgui/highgui.hpp>
  5. #include <opencv2/opencv.hpp>
  6. #include "OTSParticle.h"
  7. #include "OTSImageProcessParam.h"
  8. #include <OTSFieldData.h>
  9. #include "OTSMorphology.h"
  10. using namespace cv;
  11. using namespace std;
  12. using namespace OTSDATA;
  13. /***** 求两点间距离*****/
  14. float getDistance(Point pointO, Point pointA)
  15. {
  16. float distance;
  17. distance = powf((pointO.x - pointA.x), 2) + powf((pointO.y - pointA.y), 2);
  18. distance = sqrtf(distance);
  19. return distance;
  20. }
  21. /***** 点到直线的距离:P到AB的距离*****/
  22. //P为线外一点,AB为线段两个端点
  23. float getDist_P2L(Point pointP, Point pointA, Point pointB)
  24. {
  25. //求直线方程
  26. int A = 0, B = 0, C = 0;
  27. A = pointA.y - pointB.y;
  28. B = pointB.x - pointA.x;
  29. C = pointA.x * pointB.y - pointA.y * pointB.x;
  30. //代入点到直线距离公式
  31. float distance = 0;
  32. distance = ((float)abs(A * pointP.x + B * pointP.y + C)) / ((float)sqrtf(A * A + B * B));
  33. return distance;
  34. }
  35. int Side(Point P1, Point P2, Point point)
  36. {
  37. /*Point P1 = line.P1;
  38. Point P2 = line.P2;*/
  39. return ((P2.y - P1.y) * point.x + (P1.x - P2.x) * point.y + (P2.x * P1.y - P1.x * P2.y));
  40. }
  41. void FindInnerCircleInContour(vector<Point> contour, Point& center, int& radius)
  42. {
  43. Rect r = boundingRect(contour);
  44. int nL = r.x, nR = r.br().x; //轮廓左右边界
  45. int nT = r.y, nB = r.br().y; //轮廓上下边界
  46. double dist = 0;
  47. double maxdist = 0;
  48. for (int i = nL; i < nR; i++) //列
  49. {
  50. for (int j = nT; j < nB; j++) //行
  51. {
  52. //计算轮廓内部各点到最近轮廓点的距离
  53. dist = pointPolygonTest(contour, Point(i, j), true);
  54. if (dist > maxdist)
  55. {
  56. //求最大距离,只有轮廓最中心的点才距离最大
  57. maxdist = dist;
  58. center = Point(i, j);
  59. }
  60. }
  61. }
  62. radius = maxdist; //圆半径
  63. }
  64. BOOL GetParticleAverageChord(std::vector<Point> listEdge, double a_PixelSize, double& dPartFTD)
  65. {
  66. // safety check
  67. double nx = 0, ny = 0;
  68. Moments mu;
  69. mu = moments(listEdge, false);
  70. nx = mu.m10 / mu.m00;
  71. ny = mu.m01 / mu.m00;
  72. //circle(cvcopyImg, Point(nx, ny), 1, (255), 1);
  73. Point ptCenter = Point((int)nx, (int)ny);
  74. // coordinate transformation
  75. Point ptPosition;
  76. int radiusNum = 0;
  77. // get ferret diameter
  78. double sumFltDiameter = 0;
  79. int interval;
  80. int edgePointNum = listEdge.size();
  81. if (edgePointNum > 10)
  82. {
  83. interval = edgePointNum / 10;//get one line per 10 degree aproxemately
  84. }
  85. else
  86. {
  87. interval = 1;
  88. }
  89. for (int i = 0; i < edgePointNum; i++)
  90. {
  91. Point pt = listEdge[i];
  92. ptPosition.x = abs(pt.x - ptCenter.x);
  93. ptPosition.y = abs(pt.y - ptCenter.y);
  94. if (i % interval == 0)//calculate one line per 10 point ,so to speed up.don't calculate all the diameter.
  95. {
  96. double r1 = sqrt(pow(ptPosition.x, 2) + pow(ptPosition.y, 2));
  97. sumFltDiameter += r1;
  98. radiusNum += 1;
  99. //line(cvImageData, ptCenter, pt, Scalar(nBlackColor), nThickness, nLineType);
  100. }
  101. }
  102. if (radiusNum == 0)
  103. {
  104. dPartFTD = 0;
  105. }
  106. else
  107. {
  108. dPartFTD = a_PixelSize * sumFltDiameter / radiusNum * 2;
  109. }
  110. //imshow("feret center", cvImageData);
  111. return TRUE;
  112. }
  113. void linearSmooth5(WORD wordIn[], WORD wordOut[], int N = 255)//smooth algorithm
  114. {
  115. double in[256];
  116. double out[256];
  117. double smoothCurveData[256];
  118. for (int i = 0; i < 256; i++)
  119. {
  120. in[i] = (double)wordIn[i];
  121. }
  122. int i;
  123. if (N < 5)
  124. {
  125. for (i = 0; i <= N - 1; i++)
  126. {
  127. out[i] = in[i];
  128. }
  129. }
  130. else
  131. {
  132. out[0] = (3.0 * in[0] + 2.0 * in[1] + in[2] - in[4]) / 5.0;
  133. out[1] = (4.0 * in[0] + 3.0 * in[1] + 2 * in[2] + in[3]) / 10.0;
  134. for (i = 2; i <= N - 3; i++)
  135. {
  136. out[i] = (in[i - 2] + in[i - 1] + in[i] + in[i + 1] + in[i + 2]) / 5.0;
  137. }
  138. out[N - 2] = (4.0 * in[N - 1] + 3.0 * in[N - 2] + 2 * in[N - 3] + in[N - 4]) / 10.0;
  139. out[N - 1] = (3.0 * in[N - 1] + 2.0 * in[N - 2] + in[N - 3] - in[N - 5]) / 5.0;
  140. }
  141. for (int i = 0; i < N; i++)
  142. {
  143. wordOut[i] = (WORD)out[i];
  144. }
  145. }
  146. void BlurImage(CBSEImgPtr inImg)
  147. {
  148. int rows, cols;
  149. cols = inImg->GetWidth();
  150. rows = inImg->GetHeight();
  151. BYTE* pPixel = inImg->GetImageDataPointer();
  152. Mat cvcopyImg = Mat(rows, cols, CV_8UC1, pPixel);
  153. //Mat blurImg;
  154. //medianBlur(cvcopyImg, cvcopyImg, 11);//get rid of the noise point.
  155. //cv::bilateralFilter
  156. cv::GaussianBlur(cvcopyImg, cvcopyImg, Size(5, 5), 2);
  157. //inImg->SetImageData(cvcopyImg.data, width, height);
  158. /*outImg = inImg;*/
  159. }
  160. Mat GetMatDataFromBseImg(CBSEImgPtr inImg)
  161. {
  162. int rows, cols;
  163. cols = inImg->GetWidth();
  164. rows = inImg->GetHeight();
  165. BYTE* pPixel = inImg->GetImageDataPointer();
  166. Mat cvcopyImg = Mat(rows, cols, CV_8UC1, pPixel);
  167. return cvcopyImg;
  168. }
  169. CBSEImgPtr GetBSEImgFromMat(Mat inImg)
  170. {
  171. CBSEImgPtr bse = CBSEImgPtr(new CBSEImg(CRect(0, 0, inImg.cols, inImg.rows)));
  172. BYTE* pPixel = inImg.data;
  173. bse->SetImageData(pPixel, inImg.cols, inImg.rows);
  174. return bse;
  175. }
  176. /***********************************************************
  177. 增强算法的原理在于先统计每个灰度值在整个图像中所占的比例
  178. 然后以小于当前灰度值的所有灰度值在总像素中所占的比例,作为增益系数
  179. 对每一个像素点进行调整。由于每一个值的增益系数都是小于它的所有值所占
  180. 的比例和。所以就使得经过增强之后的图像亮的更亮,暗的更暗。
  181. ************************************************************/
  182. void ImageStretchByHistogram(const Mat& src, Mat& dst)
  183. {
  184. //判断传入参数是否正常
  185. if (!(src.size().width == dst.size().width))
  186. {
  187. cout << "error" << endl;
  188. return;
  189. }
  190. double p[256], p1[256], num[256];
  191. memset(p, 0, sizeof(p));
  192. memset(p1, 0, sizeof(p1));
  193. memset(num, 0, sizeof(num));
  194. int height = src.size().height;
  195. int width = src.size().width;
  196. long wMulh = height * width;
  197. //统计每一个灰度值在整个图像中所占个数
  198. for (int x = 0; x < width; x++)
  199. {
  200. for (int y = 0; y < height; y++)
  201. {
  202. uchar v = src.at<uchar>(y, x);
  203. num[v]++;
  204. }
  205. }
  206. //使用上一步的统计结果计算每一个灰度值所占总像素的比例
  207. for (int i = 0; i < 256; i++)
  208. {
  209. p[i] = num[i] / wMulh;
  210. }
  211. //计算每一个灰度值,小于当前灰度值的所有灰度值在总像素中所占的比例
  212. //p1[i]=sum(p[j]); j<=i;
  213. for (int i = 0; i < 256; i++)
  214. {
  215. for (int k = 0; k <= i; k++)
  216. p1[i] += p[k];
  217. }
  218. //以小于当前灰度值的所有灰度值在总像素中所占的比例,作为增益系数对每一个像素点进行调整。
  219. for (int y = 0; y < height; y++)
  220. {
  221. for (int x = 0; x < width; x++) {
  222. uchar v = src.at<uchar>(y, x);
  223. dst.at<uchar>(y, x) = p1[v] * 255 + 0.5;
  224. }
  225. }
  226. return;
  227. }
  228. //调整图像对比度
  229. Mat AdjustContrastY(const Mat& img)
  230. {
  231. Mat out = Mat::zeros(img.size(), CV_8UC1);
  232. Mat workImg = img.clone();
  233. //对图像进行对比度增强
  234. ImageStretchByHistogram(workImg, out);
  235. return Mat(out);
  236. }
  237. void CVRemoveBG(const cv::Mat& img, cv::Mat& dst,int bgstart,int bgend, long& nNumParticle)
  238. {
  239. int min_gray = bgstart;
  240. int max_gray = bgend;
  241. if (img.empty())
  242. {
  243. std::cout << "图像为空";
  244. return;
  245. }
  246. Mat image = img.clone();
  247. if (image.channels() != 1)
  248. {
  249. cv::cvtColor(image, image, cv::COLOR_BGR2GRAY);
  250. }
  251. //lut 查找表 取规定范围的灰度图 排除拼图时四周灰度为255区域 以及 灰度值较低的区域
  252. uchar lutvalues[256];
  253. for (int i = 0; i < 256; i++)
  254. {
  255. if (i < min_gray || i > max_gray)
  256. {
  257. lutvalues[i] = i;
  258. nNumParticle++;
  259. }
  260. else
  261. {
  262. lutvalues[i] = 0;
  263. }
  264. }
  265. cv::Mat lutpara(1, 256, CV_8UC1, lutvalues);
  266. cv::LUT(image, lutpara, image);
  267. cv::Mat out_fill0, out_fill;
  268. //开运算 获得x>5 的元素
  269. cv::morphologyEx(image, out_fill0, cv::MorphTypes::MORPH_OPEN, cv::getStructuringElement(0, cv::Size(5, 1)), cv::Point(-1, -1), 1);
  270. cv::morphologyEx(image, out_fill, cv::MorphTypes::MORPH_OPEN, cv::getStructuringElement(0, cv::Size(1, 5)), cv::Point(-1, -1), 1);
  271. out_fill = out_fill + out_fill0;
  272. //闭运算
  273. cv::morphologyEx(out_fill, out_fill, cv::MorphTypes::MORPH_CLOSE, cv::getStructuringElement(0, cv::Size(3, 3)), cv::Point(-1, -1), 1);
  274. //二值
  275. cv::threshold(out_fill, out_fill, 1, 255, cv::ThresholdTypes::THRESH_BINARY);
  276. dst = out_fill.clone();
  277. }
  278. void RemoveBG_old(const cv::Mat& img, cv::Mat& dst, int nBGStart, int nBGEnd,long& nNumParticle)
  279. {
  280. int w, h;
  281. w = img.cols;
  282. h = img.rows;
  283. BYTE* pSrcImg = img.data;
  284. BYTE* pPixel = new BYTE[w * h];
  285. BYTE* pTempImg = new BYTE[w * h];
  286. for (unsigned int i = 0; i < w*h; i++)
  287. {
  288. if (pSrcImg[i] < nBGStart || pSrcImg[i] > nBGEnd)
  289. {
  290. pPixel[i] = 255;
  291. nNumParticle++;
  292. }
  293. else
  294. {
  295. pPixel[i] = 0;
  296. }
  297. }
  298. int errodDilateParam =5;
  299. if (errodDilateParam > 0)
  300. {
  301. BErode3(pPixel, pTempImg, errodDilateParam, h, w);
  302. BDilate3(pTempImg, pPixel, errodDilateParam, h, w);
  303. }
  304. dst.data = pPixel;
  305. delete[] pTempImg;
  306. }