#include "VerificationTools.h" #include #include "VerificationTools.h" #include #include #include using namespace std; using namespace cv; void test() { int ptsNum = 200; //vector roiLesion(ptsNum); //cv::imread(""); } bool JudgeRoi(Rect& roi, int srcW, int srcH) { if (roi.x < 0) { roi.x = 0; } if (roi.y < 0) { roi.y = 0; } if ((roi.x + roi.width >= srcW - 1)) { roi.width = srcW - 1 - roi.x; } if (roi.y + roi.height >= srcH - 1) { roi.height = srcH - 1 - roi.y; } return true; } void __cdecl BreastDescriptionLesionsRect(int imgW, int imgH, MyPoint* contourPts, int contourLen, RoiCoor lesionRectPr, int& sameLesion) { try { Mat lesionImagePr = Mat::zeros(imgH, imgW, CV_8UC1); Point pt1[4], pt2; Point rookPoints[1][4]; rookPoints[0][0].x = lesionRectPr.x; rookPoints[0][0].y = lesionRectPr.y; rookPoints[0][1].x = lesionRectPr.x + lesionRectPr.width; rookPoints[0][1].y = lesionRectPr.y; rookPoints[0][2].x = lesionRectPr.x + lesionRectPr.width; rookPoints[0][2].y = lesionRectPr.y + lesionRectPr.height; rookPoints[0][3].x = lesionRectPr.x; rookPoints[0][3].y = lesionRectPr.y + lesionRectPr.height; const Point* ppt[1] = { rookPoints[0] }; int npt[] = { 4 }; cv::fillPoly(lesionImagePr, ppt,npt, 1, 50); int contLen = contourLen; vector contour = vector(contLen); vector> contours; MyPoint p; Point pt; for (int ni = 0; ni < contLen; ni++) { p = contourPts[ni]; pt = Point(p.x, p.y); contour[ni] = pt; } contours.push_back(contour); //cv::drawContours(lesionImage, contours, 0, Scalar(51), -1, LINE_8);//CV_FILLED或者负值表示填充,正值代表宽度 Mat lesionImageGt = Mat::zeros(imgH, imgW, CV_8UC1); Rect lesionROI = cv::boundingRect(contour); cv::rectangle(lesionImageGt, lesionROI, 50, -1); //轮廓的外接矩形 /*lesionRect.x = lesionROI.x; lesionRect.y = lesionROI.y; lesionRect.width = lesionROI.width; lesionRect.height = lesionROI.height;*/ Mat dst = lesionImageGt + lesionImagePr; int areaNum = countNonZero(dst); threshold(dst, dst, 51,255, THRESH_BINARY); int repeatNum = countNonZero(dst); float ratio = 0; if (areaNum > 0) { ratio = (float)repeatNum / (float)areaNum; } if (ratio > 0.25) { sameLesion = 1; } } catch (...) { return; } } void __cdecl DescriptionLesionsRect(int imgW, int imgH, MyPoint* contourPts, int contourLen, RoiCoor& lesionRectPr) { try { Mat lesionImage = Mat::zeros(imgH, imgW, CV_8UC1); int contLen = contourLen; vector contour = vector(contLen); vector> contours; MyPoint p; Point pt; for (int ni = 0; ni < contLen; ni++) { p = contourPts[ni]; pt = Point(p.x, p.y); contour[ni] = pt; } contours.push_back(contour); //cv::drawContours(lesionImage, contours, 0, Scalar(51), -1, LINE_8);//CV_FILLED或者负值表示填充,正值代表宽度 Rect lesionROI = cv::boundingRect(contour); lesionROI.x = lesionROI.x - 10; lesionROI.y = lesionROI.y - 10; lesionROI.width = lesionROI.width + 20; lesionROI.height = lesionROI.height + 20; JudgeRoi(lesionROI, imgW, imgH); lesionRectPr.x = lesionROI.x - 10; lesionRectPr.y = lesionROI.y - 10; lesionRectPr.width = lesionROI.width + 20; lesionRectPr.height = lesionROI.height + 20; } catch (...) { return; } } //用于胆囊壁标注数据, void __cdecl GallGetContours(char* name, int nameLen, __inout MyPoint* contour_points_out, __inout MyPoint* contour_points_in, __inout int* contourLen) { //FILE* fp; //fp = fopen("e:\\image\\nameGall.csv", "a+"); //设置保存文件 //fprintf(fp, "%s,%d,\n", name, 1);//写入 //fclose(fp); //sprintf(name, "D:\\imaged\\vediostatic\\43.0_%d.jpg", k); string imgId = name; string pathOut = "E:\\image\\胆囊\\标注\\data3\\maskout\\" + imgId + ".jpg"; //外轮廓mask string pathIn = "E:\\image\\胆囊\\标注\\data3\\maskin\\" + imgId + ".jpg"; //内轮廓mask Mat out = cv::imread(pathOut,0); Mat in = cv::imread(pathIn,0); /*if (out.empty() || in.empty()) { contourLen[0] = 0; contourLen[1] = 0; return; }*/ if (!out.empty()) { vector> outPts; cv::findContours(out, outPts, RETR_EXTERNAL, CHAIN_APPROX_NONE); int outNum = outPts[0].size(); for (int i = 0;i < outNum; i++) { contour_points_out[i].x = outPts[0][i].x; contour_points_out[i].y = outPts[0][i].y; } contourLen[0] = outPts[0].size(); } if (!in.empty()) { vector> inPts; cv::findContours(in, inPts, RETR_EXTERNAL, CHAIN_APPROX_NONE); int inNum = inPts[0].size(); for (int i = 0;i < inNum; i++) { contour_points_in[i].x = inPts[0][i].x; contour_points_in[i].y = inPts[0][i].y; } contourLen[1] = inPts[0].size(); } } //处理数据,生成模型需要的输入 //当前模型需要四通道数据,前三通道为bgr原图,最后一个通道为将病灶挖出的图 //modelW,modelH,modelChannel模型需要的输入尺寸 //RoiCoor:从原图上截取的roi坐标 void __cdecl ThyroidDescriptionModelProcess(__in unsigned char* imgData, int channel, int imgW, int imgH, RoiCoor roiVec, int ptsNum1, MyPoint* thyroidPts, int ptsNum2, MyPoint* lesionPts, int modelW, int modelH, int modelChannel, RoiCoor& roiDst, __out unsigned char* imgDataDst) { try { if (imgData == NULL) { return; } if (!(channel == 1 || channel == 3 || channel == 4)) { return; } Mat srcImg(cv::Size(imgW, imgH), CV_8UC(channel), imgData); Mat grayImg(srcImg.size(), srcImg.depth()); if (channel > 1) { cv::cvtColor(srcImg, grayImg, COLOR_BGR2GRAY); } else { grayImg = srcImg.clone(); } cv::Rect roi; bool existRoi = false; if (existRoi == true) { roi.x = roiVec.x; roi.y = roiVec.y; roi.width = roiVec.width; roi.height = roiVec.height; } else { vector lesionContTemp(ptsNum2); for (int i = 0; i < ptsNum2; i++) { lesionContTemp[i].x = lesionPts[i].x; lesionContTemp[i].y = lesionPts[i].y; } roi = cv::boundingRect(lesionContTemp); //部分数据在标注时存在偏差,可能会出现钙化超出病灶的情况,适当扩大ROI区域 roi.x -= 10; roi.y -= 10; roi.width += 20; roi.height += 20; } JudgeRoi(roi, imgW, imgH); roiDst.x = roi.x; roiDst.y = roi.y; roiDst.width = roi.width; roiDst.height = roi.height; Mat roiImg = grayImg(roi); Mat roiImgSrc = srcImg(roi); //vector thyroidCont(ptsNum1); vector thyroidCont; Point pt; for (int i = 0; i < ptsNum1; i++) { if (thyroidPts[i].x < 0) { thyroidPts[i].x = 0; } else if (thyroidPts[i].x >= imgW) { thyroidPts[i].x = imgW - 1; } if (thyroidPts[i].y < 0) { thyroidPts[i].y = 0; } else if (thyroidPts[i].y >= imgH) { thyroidPts[i].y = imgH - 1; } pt.x = thyroidPts[i].x; pt.y = thyroidPts[i].y; thyroidCont.push_back(pt); } ptsNum1 = thyroidCont.size(); vector lesionCont(ptsNum2); vector lesionContSrc(ptsNum2); for (int i = 0; i < ptsNum2; i++) { lesionCont[i].x = lesionPts[i].x - roi.x; lesionCont[i].y = lesionPts[i].y - roi.y; lesionContSrc[i].x = lesionPts[i].x; lesionContSrc[i].y = lesionPts[i].y; } Mat cropLesionMask = Mat::zeros(cv::Size(roi.width, roi.height), CV_8UC1); vector> contours; contours.push_back(lesionCont); cv::drawContours(cropLesionMask, contours, 0, Scalar(255), FILLED, LINE_8);//CV_FILLED或者负值表示填充,正值代表宽度 Mat cropLesionImg; cv::bitwise_and(roiImg, cropLesionMask, cropLesionImg); #ifdef _DEBUG //Mat showSrcImg(cv::Size(imgW, imgH), CV_8UC(3), imgData); Mat showSrcImg = srcImg.clone(); if (showSrcImg.channels() < 3) { cv::cvtColor(showSrcImg, showSrcImg, COLOR_GRAY2BGR); } for (int i = 0; i < ptsNum1; i++) { showSrcImg.at(thyroidCont[i].y, thyroidCont[i].x) = Vec3b(0, 255, 0); } #endif Mat modelImage; if (modelChannel == 4) { modelImage = Mat(cv::Size(imgW, imgH), CV_8UC4); modelImage = Mat(cv::Size(imgW, imgH), CV_8UC4); Mat dstSingle[4]; if (channel == 1) { dstSingle[0] = roiImgSrc; dstSingle[1] = roiImgSrc; dstSingle[2] = roiImgSrc; dstSingle[3] = cropLesionImg; } else if (channel == 3) { Mat single[3]; cv::split(roiImgSrc, single); dstSingle[0] = single[0]; dstSingle[1] = single[1]; dstSingle[2] = single[2]; dstSingle[3] = cropLesionImg; } else if (channel == 4) { Mat single[4]; cv::split(roiImgSrc, single); dstSingle[0] = single[0]; dstSingle[1] = single[1]; dstSingle[2] = single[2]; dstSingle[3] = cropLesionImg; } cv::merge(dstSingle, 4, modelImage); Mat dst; cv::resize(modelImage, dst, cv::Size(modelW, modelH), INTER_NEAREST);//在此处进行resize //imgDataDst = modelImage.data; memcpy(imgDataDst, dst.data, sizeof(char) * modelW * modelH * modelChannel); } } catch (...) { return; } } //处理钙化模型得到的钙化数据,求出每个钙化区域的轮廓点 void __cdecl ThyroidDescriptionModelProcessModelImage(__in unsigned char* imgModelData, int imgModelW, int imgModelH, int channelModel, RoiCoor roiModelVec, int& contourNum, int* contourLen, __inout MyPoint* calcificationPts) { int size = imgModelW * imgModelH; char* data = new char[size]; for (int nj = 0; nj < size; nj++)//第一通道为背景 { data[nj] = imgModelData[size + nj]; } Mat srcImgModel(cv::Size(imgModelW, imgModelH), CV_8UC1, data); Mat dst; int lesionW = roiModelVec.width; int lesionH = roiModelVec.height; cv::resize(srcImgModel, dst, cv::Size(lesionW, lesionH), INTER_NEAREST);//在此处进行resize vector> contours; //钙化区域的区域轮廓 cv::findContours(dst, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE); int calNum = contours.size(); contourNum = calNum; Point pt = Point(0, 0); int startInd = 0; for (int i = 0; i < calNum; i++) { vector contour = contours[i]; int len = contour.size(); for (int j = 0; j < len; j++) { pt = contour[j]; calcificationPts[startInd + j].x = pt.x + roiModelVec.x; calcificationPts[startInd + j].y = pt.y + roiModelVec.y; } contourLen[i] = len; startInd += len; } //释放内存 delete[] data; } // void __cdecl ThyroidDescriptionContour(__in unsigned char* imgData, int channel, int imgW, int imgH, RoiCoor roiVec, int ptsNum1, MyPoint* lesionPts, RoiCoor& roiDst) { if (imgData == NULL) { return; } if (!(channel == 1 || channel == 3 || channel == 4)) { return; } Mat srcImg(cv::Size(imgW, imgH), CV_8UC(channel), imgData); Mat grayImg(srcImg.size(), srcImg.depth()); if (channel > 1) { cv::cvtColor(srcImg, grayImg, COLOR_BGR2GRAY); } else { grayImg = srcImg.clone(); } cv::Rect roi; bool existRoi = false; if (existRoi == true) { roi.x = roiVec.x; roi.y = roiVec.y; roi.width = roiVec.width; roi.height = roiVec.height; } else { vector lesionContTemp(ptsNum1); for (int i = 0; i < ptsNum1; i++) { lesionContTemp[i].x = lesionPts[i].x; lesionContTemp[i].y = lesionPts[i].y; } roi = cv::boundingRect(lesionContTemp); roi.x -= 10; roi.y -= 10; roi.width += 20; roi.height += 20; } JudgeRoi(roi, imgW, imgH); //Mat roiImg = grayImg(roi); //Point pt; //vector lesionCont(ptsNum1); //vector lesionContSrc(ptsNum1); //for (int i = 0; i < ptsNum1; i++) //{ // lesionCont[i].x = lesionPts[i].x - roi.x; // lesionCont[i].y = lesionPts[i].y - roi.y; // lesionContSrc[i].x = lesionPts[i].x; // lesionContSrc[i].y = lesionPts[i].y; //} //Mat lesionMask = Mat::zeros(roi.height, roi.width, CV_8UC1); //vector> contours; //contours.push_back(lesionCont); //cv::drawContours(lesionMask, contours, 0, Scalar(255), FILLED, LINE_8);//CV_FILLED或者负值表示填充,正值代表宽度 //vector > contour_vec; //vector hierarchy; //findContours(lesionMask, contour_vec, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_NONE); //Rect boundRect; //boundRect = boundingRect(Mat(contour_vec[0])); ////Mat imageContoursrect = Mat::zeros(lesionMask.size(), CV_8UC1); //最小外接正矩形画布 ////rectangle(imageContoursrect, Point(boundRect.x, boundRect.y), Point(boundRect.x + boundRect.width, boundRect.y + boundRect.height), Scalar(255), 2, 8); ////Rect rect = minAreaRect(contour_vec[0]); //roiDst.x = boundRect.x + roi.x; //roiDst.y = boundRect.y + roi.y; //roiDst.width = boundRect.width; //roiDst.height = boundRect.height; roiDst.x = roi.x; roiDst.y = roi.y; roiDst.width = roi.width; roiDst.height = roi.height; } void __cdecl video2image() { VideoCapture capture("E:\\image\\颈动脉\\hor1.mp4"); if (!capture.isOpened()) { return; } int frameH = capture.get(CAP_PROP_FRAME_HEIGHT); int frameW = capture.get(CAP_PROP_FRAME_WIDTH); int fps = capture.get(CAP_PROP_FPS); long numFrames = capture.get(CAP_PROP_FRAME_COUNT); //printf("vedio's width = %d\t height = %d\nvideo's fps = %d\t nums = %d", frameW, frameH, fps, numFrames); int imgIndex = 1; while (1) { //std::cout << "第" << imgIndex << "幅图像" << std::endl; Mat frame; capture >> frame; if (frame.empty()) { break; } //char* imageSaveName = new char[200]; char imageSaveName[512]; //将图片的路径及名称输入到imageSaveName中 //string path = "D:\\imaged\\甲状腺\\20221213\\2022-11-29\\[zhangya--2-甲y]-[20221123003]-[55df3ec4-5d38-4e37-aff3-f5cd0083b761]\\3\\1129_10_3_" + to_string(imgIndex) + ".png"; sprintf_s(imageSaveName, "E:\\image\\颈动脉\\hor1\\230914%05d.jpg", imgIndex); //将每一帧图像frame保存到imageSaveName指定的文件中 imwrite(imageSaveName, frame); //delete[] imageSaveName;_ imgIndex++; /*if (waitKey(20) > 0) { break; }*/ if (imgIndex > 4000) { break; } } capture.release(); //cout << "total frames: " << imgIndex << endl; } void __cdecl Image_to_video_2() { char filename[100]; VideoWriter writer; int codec = writer.fourcc('X', 'V', 'I', 'D'); VideoWriter video("D:\\imaged\\甲状腺\\视频\\img.mp4", codec, 10.0, Size(596, 650), true); String img_path = "D:\\imaged\\甲状腺\\视频\\img\\*.jpg"; vector imgname; glob(img_path, imgname, false); //glob:获取文件路径下的所有图片 size_t count = imgname.size(); for (size_t i = 0; i < count; i++) //for (int i = 1; i <= 10; i++) { sprintf(filename, "D:\\imaged\\甲状腺\\视频\\img\\230801%05d.jpg", i); string ss = imgname[i].c_str(); Mat image = imread(ss); //resize(image, image, Size(1920, 1080)); video << image; } } //用于胆囊病灶标注数据, void __cdecl GallLesionGetContours(char* name, int nameLen, __inout MyPoint* contour_points, __inout int* contourLen, int& GallLesionNum) { //FILE* fp; //fp = fopen("e:\\image\\nameGall.csv", "a+"); //设置保存文件 //fprintf(fp, "%s,%d,\n", name, 1);//写入 //fclose(fp); //sprintf(name, "D:\\imaged\\vediostatic\\43.0_%d.jpg", k); string imgId = name; string path = "F:\\image\\胆囊疾病\\gall2\\mask\\" /*+ imgId + ".jpg"*/; //外轮廓mask //string pathIn = "E:\\image\\胆囊\\标注\\data4\\maskin\\" + imgId + ".jpg"; //内轮廓mask vector imgName; int lesionNum = 0; int ptsNum = 0; for (int i = 0; i < 10;i++) { string ss = to_string(i); string name = path + imgId + "_" + ss + ".jpg"; Mat img = cv::imread(name, 0); if (!img.empty()) { vector> outPts; cv::findContours(img, outPts, RETR_EXTERNAL, CHAIN_APPROX_NONE); int outNum = outPts[0].size(); for (int j = 0;j < outNum; j++) { contour_points[ptsNum + j].x = outPts[0][j].x; contour_points[ptsNum + j].y = outPts[0][j].y; } ptsNum = ptsNum + outNum; contourLen[i] = outPts[0].size(); lesionNum++; } } GallLesionNum = lesionNum; }