diff --git a/src/PBBiology/include/PBImageProcess.h b/src/PBBiology/include/PBImageProcess.h index 5c8ba53..5e95fb8 100644 --- a/src/PBBiology/include/PBImageProcess.h +++ b/src/PBBiology/include/PBImageProcess.h @@ -10,28 +10,28 @@ using namespace std; using namespace cv; -//生长函数 +//鐢熼暱鍑芥暟 int RegionGrow(cv::Mat& src, cv::Mat& matDst, cv::Point2i pt, int th); -//最小二乘法取圆 +//鏈灏忎簩涔樻硶鍙栧渾 void FitCircleCenter(vector& Circle_Data, Point2f& Circle_Center, float& Circle_R); -//最优最小二乘法取圆 +//鏈浼樻渶灏忎簩涔樻硶鍙栧渾 int RANSAC_FitCircleCenter(vector& Circle_Data, Point2f& Circle_Center, float& Circle_R, float thresh); -//生长最优最小二乘法取圆 +//鐢熼暱鏈浼樻渶灏忎簩涔樻硶鍙栧渾 void RANSAC_FitCircleCenter_with_throw(vector& Circle_Data, Point2f& Circle_Center, float& Circle_R); -//二值化阈值计算 +//浜屽煎寲闃堝艰绠 int IJIsoData(int* data); int defaultIsoData(int* data); -////根据mask渲染图像 -////src、mask:输入CV_16UC1图像 -////dst:输出CV_8UC3彩色图像 -////max、min:mask像素选择渲染的最大最小值 -////color:颜色类型 -////reverse:是否反转颜色 +////鏍规嵁mask娓叉煋鍥惧儚 +////src銆乵ask锛氳緭鍏V_16UC1鍥惧儚 +////dst锛氳緭鍑篊V_8UC3褰╄壊鍥惧儚 +////max銆乵in锛歮ask鍍忕礌閫夋嫨娓叉煋鐨勬渶澶ф渶灏忓 +////color锛氶鑹茬被鍨 +////reverse锛氭槸鍚﹀弽杞鑹 //int render_mask_image(Mat src, Mat mask, Mat dst, float max, float min, ColorTable color, bool reverse); // ///// -///// 融合两张图 +///// 铻嶅悎涓ゅ紶鍥 ///// ///// ///// @@ -40,41 +40,41 @@ int defaultIsoData(int* data); ///// //int blendImages(const Mat& src, const Mat& mark, const Mat& dst, double alpha); ////int render_image(Mat src, Mat& dst, float max, float min, ColorTable color, bool reverse); -////合成渲染图像,src是老鼠图,pseudoImg是光子渲染图,brightness_offset亮度,contrast_factor对比度,contrast_factor透明度,返回融合图 -////brightness_offset:亮度偏移范围 -255 到 +255 -////contrast_factor:对比度因子范围 0.1 到 3.0(1.0为不变) -////opacity_factor:透明度因子范围 0 到 1(0为透明,1为不透明) +////鍚堟垚娓叉煋鍥惧儚锛宻rc鏄侀紶鍥撅紝pseudoImg鏄厜瀛愭覆鏌撳浘锛宐rightness_offset浜害锛宑ontrast_factor瀵规瘮搴︼紝contrast_factor閫忔槑搴︼紝杩斿洖铻嶅悎鍥 +////brightness_offset:浜害鍋忕Щ鑼冨洿 -255 鍒 +255 +////contrast_factor:瀵规瘮搴﹀洜瀛愯寖鍥 0.1 鍒 3.0锛1.0涓轰笉鍙橈級 +////opacity_factor:閫忔槑搴﹀洜瀛愯寖鍥 0 鍒 1锛0涓洪忔槑锛1涓轰笉閫忔槑锛 //Mat render_mask_image(Mat src, Mat pseudoImg, int brightness_offset, double contrast_factor, double opacity_factor); -////获取颜色表,color颜色类型,bgr_tab是有空间的颜色表指针,reverse是否反转 +////鑾峰彇棰滆壊琛紝color棰滆壊绫诲瀷锛宐gr_tab鏄湁绌洪棿鐨勯鑹茶〃鎸囬拡锛宺everse鏄惁鍙嶈浆 //void get_bgr_tab(ColorTable color, uint8_t(*bgr_tab)[3], bool reverse); -////生产颜色表的直条图,w=200,h_color=10是一个颜色高,bgr_tab是有空间的颜色表指针 +////鐢熶骇棰滆壊琛ㄧ殑鐩存潯鍥撅紝w=200,h_color=10鏄竴涓鑹查珮锛宐gr_tab鏄湁绌洪棿鐨勯鑹茶〃鎸囬拡 //Mat bgr_tab_image(int w, int h_onecolor, uint8_t(*bgr_tab)[3]); //int pseudo_color_processing(Mat src, Mat dst, float max, float min, uint8_t(*bgr_tab)[3]); // -//// 获得选中区域的光子数 +//// 鑾峰緱閫変腑鍖哄煙鐨勫厜瀛愭暟 //PseudoInfo get_pseudo_info(Mat src,int x,int y,int w,int h,float max,float min); // //Mat bgr_scale_image(Mat src, float maxVal, float minVal); -//合成渲染图像,src是老鼠图,pseudoImg是光子渲染图,brightness_offset亮度,contrast_factor对比度,contrast_factor透明度,返回融合图 -//brightness_offset:亮度偏移范围 -255 到 +255 -//contrast_factor:对比度因子范围 0.1 到 3.0(1.0为不变) -//opacity_factor:透明度因子范围 0 到 1(0为透明,1为不透明) +//鍚堟垚娓叉煋鍥惧儚锛宻rc鏄侀紶鍥撅紝pseudoImg鏄厜瀛愭覆鏌撳浘锛宐rightness_offset浜害锛宑ontrast_factor瀵规瘮搴︼紝contrast_factor閫忔槑搴︼紝杩斿洖铻嶅悎鍥 +//brightness_offset:浜害鍋忕Щ鑼冨洿 -255 鍒 +255 +//contrast_factor:瀵规瘮搴﹀洜瀛愯寖鍥 0.1 鍒 3.0锛1.0涓轰笉鍙橈級 +//opacity_factor:閫忔槑搴﹀洜瀛愯寖鍥 0 鍒 1锛0涓洪忔槑锛1涓轰笉閫忔槑锛 Mat render_mask_image(Mat src, Mat pseudoImg, int brightness_offset, double contrast_factor, double opacity_factor); -//获取颜色表,color颜色类型,bgr_tab是有空间的颜色表指针,reverse是否反转 +//鑾峰彇棰滆壊琛紝color棰滆壊绫诲瀷锛宐gr_tab鏄湁绌洪棿鐨勯鑹茶〃鎸囬拡锛宺everse鏄惁鍙嶈浆 void get_bgr_tab(ColorTable color, uint8_t(*bgr_tab)[3], bool reverse); -//生产颜色表的直条图,w=200,h_color=10是一个颜色高,bgr_tab是有空间的颜色表指针 +//鐢熶骇棰滆壊琛ㄧ殑鐩存潯鍥撅紝w=200,h_color=10鏄竴涓鑹查珮锛宐gr_tab鏄湁绌洪棿鐨勯鑹茶〃鎸囬拡 Mat bgr_tab_image(int w, int h_onecolor, uint8_t(*bgr_tab)[3]); -//统计计算结果,src是输入图像,16bit的count图或者float的光子计算结果图都可以输入;mask是掩膜图;max和min是设定的大小 +//缁熻璁$畻缁撴灉锛宻rc鏄緭鍏ュ浘鍍忥紝16bit鐨刢ount鍥炬垨鑰協loat鐨勫厜瀛愯绠楃粨鏋滃浘閮藉彲浠ヨ緭鍏ワ紱mask鏄帺鑶滃浘锛沵ax鍜宮in鏄瀹氱殑澶у皬 PseudoInfo get_pseudo_info(Mat src, Mat mask, float max, float min); -//生成光子渲染图,src是渲染前图,dst是渲染后图,max和min是设定的大小,bgr_tab是有空间的颜色表指针 +//鐢熸垚鍏夊瓙娓叉煋鍥撅紝src鏄覆鏌撳墠鍥撅紝dst鏄覆鏌撳悗鍥撅紝max鍜宮in鏄瀹氱殑澶у皬锛宐gr_tab鏄湁绌洪棿鐨勯鑹茶〃鎸囬拡 int pseudo_color_processing(Mat src, Mat dst, float max, float min, uint8_t(*bgr_tab)[3]); -//生成带标尺的直条图,src是bgr_tab_image生成的图,maxVal和minVal是设定的大小,scientific_flag是否科学计数法 +//鐢熸垚甯︽爣灏虹殑鐩存潯鍥撅紝src鏄痓gr_tab_image鐢熸垚鐨勫浘锛宮axVal鍜宮inVal鏄瀹氱殑澶у皬锛宻cientific_flag鏄惁绉戝璁℃暟娉 Mat bgr_scale_image(Mat src, float maxVal, float minVal, int scientific_flag); -//获取光子计算图,src输入渲染前原始图,sec是拍摄秒数,Wcm=27是实际宽,Hcm=18是实际高,sr是默认1.0;返回CV_32FC1的浮点光子结果图 +//鑾峰彇鍏夊瓙璁$畻鍥撅紝src杈撳叆娓叉煋鍓嶅師濮嬪浘锛宻ec鏄媿鎽勭鏁帮紝Wcm=27鏄疄闄呭锛孒cm=18鏄疄闄呴珮锛宻r鏄粯璁1.0锛涜繑鍥濩V_32FC1鐨勬诞鐐瑰厜瀛愮粨鏋滃浘 Mat get_photon_image(Mat src, float sec, float Wcm, float Hcm, float sr); -//魔术棒功能,src是处理成8bit的图,x,y是点击位置的坐标, -//th是设定的像素差(10或20之类的,可以实际调一下),就是和点击位置的像素差在th范围内的连在一起的像素,都会被框选 -Mat get_magic_wand_image(Mat src, int x, int y, int th); \ No newline at end of file +//榄旀湳妫掑姛鑳斤紝src鏄鐞嗘垚8bit鐨勫浘锛寈,y鏄偣鍑讳綅缃殑鍧愭爣锛宮ax鍜宮in鏄瀹氱殑澶у皬,max鍜宮in闇瑕佹敞鎰忛櫎浠256锛屼娇鐢0-255鏁版嵁 +//鐐瑰嚮浣嶇疆鐨勫儚绱犲樊鍦╗min,max]鑼冨洿鍐呯殑杩炲湪涓璧风殑鍍忕礌锛岄兘浼氳妗嗛 +Mat get_magic_wand_image(Mat src,int x,int y,float max,float min); \ No newline at end of file diff --git a/src/PBBiology/src/PBImageProcess.cpp b/src/PBBiology/src/PBImageProcess.cpp index 64c8c8a..8293479 100644 --- a/src/PBBiology/src/PBImageProcess.cpp +++ b/src/PBBiology/src/PBImageProcess.cpp @@ -2,7 +2,7 @@ #include -//区域生长算法 +//鍖哄煙鐢熼暱绠楁硶 int RegionGrow(cv::Mat& src, cv::Mat& matDst, cv::Point2i pt, int th) { cv::Point2i ptGrowing; @@ -16,39 +16,39 @@ int RegionGrow(cv::Mat& src, cv::Mat& matDst, cv::Point2i pt, int th) vcGrowPt.push_back(pt); matDst.at(pt.y, pt.x) = 255; - while (!vcGrowPt.empty()) //生长栈不为空则生长 + while (!vcGrowPt.empty()) //鐢熼暱鏍堜笉涓虹┖鍒欑敓闀 { - pt = vcGrowPt.back(); //取出一个生长点 + pt = vcGrowPt.back(); //鍙栧嚭涓涓敓闀跨偣 vcGrowPt.pop_back(); - std::vector temp_vcGrowPt; //临时生长点栈 - int temp_vcGrowPt_size = 0; //可生长方向数量,因为存在被其余生长点先生长情况,不可直接使用temp_vcGrowPt.size() + std::vector temp_vcGrowPt; //涓存椂鐢熼暱鐐规爤 + int temp_vcGrowPt_size = 0; //鍙敓闀挎柟鍚戞暟閲忥紝鍥犱负瀛樺湪琚叾浣欑敓闀跨偣鍏堢敓闀挎儏鍐碉紝涓嶅彲鐩存帴浣跨敤temp_vcGrowPt.size() nSrcValue = src.at(pt.y, pt.x); - //分别对八个方向上的点进行生长 + //鍒嗗埆瀵瑰叓涓柟鍚戜笂鐨勭偣杩涜鐢熼暱 for (int i = 0; i < 8; ++i) { ptGrowing.x = pt.x + DIR[i][0]; ptGrowing.y = pt.y + DIR[i][1]; - //检查是否是边缘点 + //妫鏌ユ槸鍚︽槸杈圭紭鐐 if (ptGrowing.x < 0 || ptGrowing.y < 0 || ptGrowing.x >(src.cols - 1) || (ptGrowing.y > src.rows - 1)) continue; - nGrowLable = matDst.at(ptGrowing.y, ptGrowing.x); //当前待生长点的灰度值 - if (nGrowLable == 0) //如果标记点还没有被生长 + nGrowLable = matDst.at(ptGrowing.y, ptGrowing.x); //褰撳墠寰呯敓闀跨偣鐨勭伆搴﹀ + if (nGrowLable == 0) //濡傛灉鏍囪鐐硅繕娌℃湁琚敓闀 { nCurValue = src.at(ptGrowing.y, ptGrowing.x); - if (abs(nCurValue - nSrcValue) < th) //在阈值范围内则生长 + if (abs(nCurValue - nSrcValue) < th) //鍦ㄩ槇鍊艰寖鍥村唴鍒欑敓闀 { // matDst.at(ptGrowing.y, ptGrowing.x) = 255; temp_vcGrowPt_size++; - temp_vcGrowPt.push_back(ptGrowing); //将下一个生长点压入栈中 + temp_vcGrowPt.push_back(ptGrowing); //灏嗕笅涓涓敓闀跨偣鍘嬪叆鏍堜腑 } } else { temp_vcGrowPt_size++; } } - //相邻的生长点不是单向生长,则生长点有效 + //鐩搁偦鐨勭敓闀跨偣涓嶆槸鍗曞悜鐢熼暱锛屽垯鐢熼暱鐐规湁鏁 if (temp_vcGrowPt_size >= 1) { mat_cnt++; matDst.at(pt.y, pt.x) = 255; @@ -56,43 +56,43 @@ int RegionGrow(cv::Mat& src, cv::Mat& matDst, cv::Point2i pt, int th) } } return mat_cnt; - // bitwise_and(src, matDst, matDst); //与运算可以保留原图像数据 + // bitwise_and(src, matDst, matDst); //涓庤繍绠楀彲浠ヤ繚鐣欏師鍥惧儚鏁版嵁 } -// 定义拟合圆形的函数 +// 瀹氫箟鎷熷悎鍦嗗舰鐨勫嚱鏁 void FitCircleCenter(vector& Circle_Data, Point2f& Circle_Center, float& Circle_R) { - //定义计算中间变量 - double sumX1 = 0.0; //代表Xi的和(从1~n) ,X1代表X的1次方 + //瀹氫箟璁$畻涓棿鍙橀噺 + double sumX1 = 0.0; //浠h〃Xi鐨勫拰(浠1~n) 锛孹1浠h〃X鐨1娆℃柟 double sumY1 = 0.0; - double sumX2 = 0.0; //代表(Xi)^2的和(i从1~n),X2代表X的二次方 + double sumX2 = 0.0; //浠h〃(Xi)^2鐨勫拰(i浠1~n)锛孹2浠h〃X鐨勪簩娆℃柟 double sumY2 = 0.0; double sumX3 = 0.0; double sumY3 = 0.0; double sumX1Y1 = 0.0; double sumX1Y2 = 0.0; double sumX2Y1 = 0.0; - const double N = (double)Circle_Data.size();//获得输入点的个数 + const double N = (double)Circle_Data.size();//鑾峰緱杈撳叆鐐圭殑涓暟 - for (int i = 0; i < Circle_Data.size(); ++i)//遍历组中所有数据 + for (int i = 0; i < Circle_Data.size(); ++i)//閬嶅巻缁勪腑鎵鏈夋暟鎹 { double x = 0; double y = 0; - x = Circle_Data[i].x; //获得组中第i个点的x坐标 - y = Circle_Data[i].y; //获得组中第i个点的y坐标 - double x2 = x * x; //计算x^2 - double y2 = y * y; //计算y^2 - double x3 = x2 * x; //计算x^3 - double y3 = y2 * y; //计算y^3 - double xy = x * y; //计算xy - double x1y2 = x * y2; //计算x*y^2 - double x2y1 = x2 * y; //计算x^2*y + x = Circle_Data[i].x; //鑾峰緱缁勪腑绗琲涓偣鐨剎鍧愭爣 + y = Circle_Data[i].y; //鑾峰緱缁勪腑绗琲涓偣鐨剏鍧愭爣 + double x2 = x * x; //璁$畻x^2 + double y2 = y * y; //璁$畻y^2 + double x3 = x2 * x; //璁$畻x^3 + double y3 = y2 * y; //璁$畻y^3 + double xy = x * y; //璁$畻xy + double x1y2 = x * y2; //璁$畻x*y^2 + double x2y1 = x2 * y; //璁$畻x^2*y - sumX1 += x; //sumX=sumX+x;计算x坐标的和 - sumY1 += y; //sumY=sumY+y;计算y坐标的和 - sumX2 += x2; //计算x^2的和 - sumY2 += y2; //计算各个点的y^2的和 - sumX3 += x3; //计算x^3的和 + sumX1 += x; //sumX=sumX+x;璁$畻x鍧愭爣鐨勫拰 + sumY1 += y; //sumY=sumY+y;璁$畻y鍧愭爣鐨勫拰 + sumX2 += x2; //璁$畻x^2鐨勫拰 + sumY2 += y2; //璁$畻鍚勪釜鐐圭殑y^2鐨勫拰 + sumX3 += x3; //璁$畻x^3鐨勫拰 sumY3 += y3; sumX1Y1 += xy; sumX1Y2 += x1y2; @@ -117,11 +117,11 @@ void FitCircleCenter(vector& Circle_Data, Point2f& Circle_Center, float& int RANSAC_FitCircleCenter(vector& Circle_Data, Point2f& Circle_Center, float& Circle_R, float thresh) { - // 定义RANSAC迭代次数和最小样本数 + // 瀹氫箟RANSAC杩唬娆℃暟鍜屾渶灏忔牱鏈暟 int iterations = 1000; int min_samples = 3; - // 使用RANSAC算法拟合圆形 + // 浣跨敤RANSAC绠楁硶鎷熷悎鍦嗗舰 float best_radius = 0; Point2f best_center; std::vector is_inlier(Circle_Data.size(), 0); @@ -132,7 +132,7 @@ int RANSAC_FitCircleCenter(vector& Circle_Data, Point2f& Circle_Center, f while (sample_count < iterations) { - // 随机选择最小样本数个点 + // 闅忔満閫夋嫨鏈灏忔牱鏈暟涓偣 vector points; for (int j = 0; j < min_samples; j++) { @@ -141,12 +141,12 @@ int RANSAC_FitCircleCenter(vector& Circle_Data, Point2f& Circle_Center, f points.push_back(point); } - // 使用最小二乘法拟合圆形 + // 浣跨敤鏈灏忎簩涔樻硶鎷熷悎鍦嗗舰 float radius; Point2f center; FitCircleCenter(points, center, radius); - // 计算所有点与圆之间的距离,以确定内点 + // 璁$畻鎵鏈夌偣涓庡渾涔嬮棿鐨勮窛绂伙紝浠ョ‘瀹氬唴鐐 vector inliers; for (int i = 0; i < Circle_Data.size(); i++) { @@ -160,28 +160,28 @@ int RANSAC_FitCircleCenter(vector& Circle_Data, Point2f& Circle_Center, f inliers.push_back(point); } } - // 更新最佳拟合圆形 + // 鏇存柊鏈浣虫嫙鍚堝渾褰 if (inliers.size() > max_inlier_num) { max_inlier_num = inliers.size(); is_inlier = is_inlier_tmp; best_radius = radius; best_center = center; } - //6. 更新迭代的最佳次数 + //6. 鏇存柊杩唬鐨勬渶浣虫鏁 if (inliers.size() == 0) { iterations = 1000; } else { - double epsilon = 1.0 - double(inliers.size()) / (double)Circle_Data.size(); //野值点比例 - double p = 0.9; //所有样本中存在1个好样本的概率 + double epsilon = 1.0 - double(inliers.size()) / (double)Circle_Data.size(); //閲庡肩偣姣斾緥 + double p = 0.9; //鎵鏈夋牱鏈腑瀛樺湪1涓ソ鏍锋湰鐨勬鐜 double s = 3.0; iterations = int(std::log(1.0 - p) / std::log(1.0 - std::pow((1.0 - epsilon), s))); } sample_count++; } - //7. 基于最优的结果所对应的内点做最终拟合 + //7. 鍩轰簬鏈浼樼殑缁撴灉鎵瀵瑰簲鐨勫唴鐐瑰仛鏈缁堟嫙鍚 std::vector inliers; inliers.reserve(max_inlier_num); for (int i = 0; i < is_inlier.size(); i++) @@ -297,9 +297,9 @@ int defaultIsoData(int* data) // { // return dst; // } -// //brightness_offset:亮度偏移范围 -255 到 +255 -// //contrast_factor:对比度因子范围 0.1 到 3.0(1.0为不变) -// //opacity_factor:透明度因子范围 0 到 1(0为透明,1为不透明) +// //brightness_offset:浜害鍋忕Щ鑼冨洿 -255 鍒 +255 +// //contrast_factor:瀵规瘮搴﹀洜瀛愯寖鍥 0.1 鍒 3.0锛1.0涓轰笉鍙橈級 +// //opacity_factor:閫忔槑搴﹀洜瀛愯寖鍥 0 鍒 1锛0涓洪忔槑锛1涓轰笉閫忔槑锛 // // Mat img8bit; // src.convertTo(img8bit, CV_8UC1, 0.00390625); @@ -311,7 +311,7 @@ int defaultIsoData(int* data) // img_with_opacity.convertTo(img_with_opacity, CV_8UC1); // // Mat img_with_opacity_rgb; -// cvtColor(img_with_opacity, img_with_opacity_rgb, COLOR_GRAY2BGR); // 将单通道灰度图像转换为三通道RGB图像 +// cvtColor(img_with_opacity, img_with_opacity_rgb, COLOR_GRAY2BGR); // 灏嗗崟閫氶亾鐏板害鍥惧儚杞崲涓轰笁閫氶亾RGB鍥惧儚 // // for (int y = 0; y < pseudoImg.rows; y++) { // for (int x = 0; x < pseudoImg.cols; x++) { @@ -424,30 +424,30 @@ Mat bgr_scale_image(Mat src, float maxVal, float minVal) //int blendImages(const Mat& src, const Mat& mark, const Mat& dst, double alpha) //{ -// // 检查输入图像的类型和大小 +// // 妫鏌ヨ緭鍏ュ浘鍍忕殑绫诲瀷鍜屽ぇ灏 // if (src.type() != CV_16UC1 || mark.type() != CV_8UC3) // { -// return -1; // 错误处理 +// return -1; // 閿欒澶勭悊 // } // -// // 将 alpha 从 0-100 的范围转换为 0-1 +// // 灏 alpha 浠 0-100 鐨勮寖鍥磋浆鎹负 0-1 // double alpha_normalized = alpha / 100.0; // -// // 将 src 从 16 位转换为 8 位 +// // 灏 src 浠 16 浣嶈浆鎹负 8 浣 // Mat src8U; -// src.convertTo(src8U, CV_8UC1, 1.0 / 256); // 将16位值缩放到0-255范围 +// src.convertTo(src8U, CV_8UC1, 1.0 / 256); // 灏16浣嶅肩缉鏀惧埌0-255鑼冨洿 // -// // 将 src8U 转换为彩色图像,以便与 mark 融合 +// // 灏 src8U 杞崲涓哄僵鑹插浘鍍忥紝浠ヤ究涓 mark 铻嶅悎 // Mat srcColor; -// cvtColor(src8U, srcColor, COLOR_GRAY2RGB); // 转换为 BGR 彩色图像 +// cvtColor(src8U, srcColor, COLOR_GRAY2RGB); // 杞崲涓 BGR 褰╄壊鍥惧儚 // -// // 创建一个输出图像 +// // 鍒涘缓涓涓緭鍑哄浘鍍 // Mat blended; // -// // 使用 addWeighted 进行融合 +// // 浣跨敤 addWeighted 杩涜铻嶅悎 // addWeighted(srcColor, 1, mark,alpha_normalized, 0.0, blended); // blended.copyTo(dst); -// return 1; // 成功 +// return 1; // 鎴愬姛 //} @@ -792,9 +792,9 @@ Mat render_mask_image(Mat src, Mat pseudoImg, int brightness_offset, double cont { return dst; } - //brightness_offset:亮度偏移范围 -255 到 +255 - //contrast_factor:对比度因子范围 0.1 到 3.0(1.0为不变) - //opacity_factor:透明度因子范围 0 到 1(0为透明,1为不透明) + //brightness_offset:浜害鍋忕Щ鑼冨洿 -255 鍒 +255 + //contrast_factor:瀵规瘮搴﹀洜瀛愯寖鍥 0.1 鍒 3.0锛1.0涓轰笉鍙橈級 + //opacity_factor:閫忔槑搴﹀洜瀛愯寖鍥 0 鍒 1锛0涓洪忔槑锛1涓轰笉閫忔槑锛 Mat img8bit; src.convertTo(img8bit, CV_8UC1, 0.00390625); @@ -806,7 +806,7 @@ Mat render_mask_image(Mat src, Mat pseudoImg, int brightness_offset, double cont img_with_opacity.convertTo(img_with_opacity, CV_8UC1); Mat img_with_opacity_rgb; - cvtColor(img_with_opacity, img_with_opacity_rgb, COLOR_GRAY2BGR); // 将单通道灰度图像转换为三通道RGB图像 + cvtColor(img_with_opacity, img_with_opacity_rgb, COLOR_GRAY2BGR); // 灏嗗崟閫氶亾鐏板害鍥惧儚杞崲涓轰笁閫氶亾RGB鍥惧儚 for (int y = 0; y < pseudoImg.rows; y++) { for (int x = 0; x < pseudoImg.cols; x++) { @@ -1212,71 +1212,68 @@ Mat get_photon_image(Mat src, float sec, float Wcm, float Hcm, float sr) return dst; } -Mat get_magic_wand_image(Mat src, int x, int y, int th) +Mat get_magic_wand_image(Mat src,int x,int y,float max,float min) { - std::cout << "1" << std::endl; Mat matDst = cv::Mat::zeros(src.size(), CV_8UC1); - std::cout << "11" << std::endl; - cv::Point2i pt(x, y); - std::cout << "12" << std::endl; - cv::Point2i ptGrowing; - std::cout << "13" << std::endl; - int nGrowLable = 0; - int nSrcValue = 0; - int nCurValue = 0; - int mat_cnt = 0; - int DIR[8][2] = { { -1, -1 }, { 0, -1 }, { 1, -1 }, { 1, 0 }, { 1, 1 }, { 0, 1 }, { -1, 1 }, { -1, 0 } }; - std::cout << "14" << std::endl; - std::vector vcGrowPt; - std::cout << "15" << std::endl; - vcGrowPt.push_back(pt); - std::cout << "16" << std::endl; - matDst.at(pt.y, pt.x) = 255; - std::cout << "17" << std::endl; - std::cout << "w:" << src.rows << "h:" << src.cols << std::endl; - std::cout << pt.y <<":1:" << pt.x << std::endl; - nSrcValue = src.at(pt.y, pt.x); - std::cout << "2" << std::endl; - while (!vcGrowPt.empty()) + cv::Point2i pt(x,y); + int w = src.cols; + int h = src.rows; + // int nSrcValue = src.at(pt.y, pt.x); + int nSrcValue = src.data[pt.y * w + pt.x]; + if(nSrcValue < min) { - pt = vcGrowPt.back(); - vcGrowPt.pop_back(); - - std::vector temp_vcGrowPt; - int temp_vcGrowPt_size = 0; - // nSrcValue = src.at(pt.y, pt.x); - //分别对八个方向上的点进行生长 - for (int i = 0; i < 8; ++i) - { - ptGrowing.x = pt.x + DIR[i][0]; - ptGrowing.y = pt.y + DIR[i][1]; - //检查是否是边缘点 - if (ptGrowing.x < 0 || ptGrowing.y < 0 || ptGrowing.x >(src.cols - 1) || (ptGrowing.y > src.rows - 1)) - continue; - - nGrowLable = matDst.at(ptGrowing.y, ptGrowing.x); //当前待生长点的灰度值 - if (nGrowLable == 0) //如果标记点还没有被生长 - { - nCurValue = src.at(ptGrowing.y, ptGrowing.x); - if (abs(nCurValue - nSrcValue) < th) //在阈值范围内则生长 - { - // matDst.at(ptGrowing.y, ptGrowing.x) = 255; - temp_vcGrowPt_size++; - temp_vcGrowPt.push_back(ptGrowing); //将下一个生长点压入栈中 - } - } - else { - temp_vcGrowPt_size++; - } - } - std::cout << "3" << std::endl; - //相邻的生长点不是单向生长,则生长点有效 - if (temp_vcGrowPt_size >= 1) { - mat_cnt++; - matDst.at(pt.y, pt.x) = 255; - vcGrowPt.insert(vcGrowPt.end(), temp_vcGrowPt.begin(), temp_vcGrowPt.end()); - } - std::cout << "4" << std::endl; + return matDst; } + + cv::Point2i ptGrowing; + int nGrowLable = 0; + int nCurValue = 0; + int mat_cnt = 0; + int DIR[8][2] = { { -1, -1 }, { 0, -1 }, { 1, -1 }, { 1, 0 }, { 1, 1 }, { 0, 1 }, { -1, 1 }, { -1, 0 } }; + std::vector vcGrowPt; + vcGrowPt.push_back(pt); + // matDst.at(pt.y, pt.x) = 255; + matDst.data[pt.y * w + pt.x] = 255; + while (!vcGrowPt.empty()) + { + pt = vcGrowPt.back(); + vcGrowPt.pop_back(); + + std::vector temp_vcGrowPt; + int temp_vcGrowPt_size = 0; + // nSrcValue = src.at(pt.y, pt.x); + //鍒嗗埆瀵瑰叓涓柟鍚戜笂鐨勭偣杩涜鐢熼暱 + for (int i = 0; i < 8; ++i) + { + ptGrowing.x = pt.x + DIR[i][0]; + ptGrowing.y = pt.y + DIR[i][1]; + //妫鏌ユ槸鍚︽槸杈圭紭鐐 + if (ptGrowing.x < 0 || ptGrowing.y < 0 || ptGrowing.x >(src.cols - 1) || (ptGrowing.y > src.rows - 1)) + continue; + + // nGrowLable = matDst.at(ptGrowing.y, ptGrowing.x); + nGrowLable = matDst.data[ptGrowing.y * w + ptGrowing.x]; //褰撳墠寰呯敓闀跨偣鐨勭伆搴﹀ + if (nGrowLable == 0) //濡傛灉鏍囪鐐硅繕娌℃湁琚敓闀 + { + nCurValue = src.data[ptGrowing.y * w + ptGrowing.x]; + if (nCurValue >= min) //鍦ㄩ槇鍊艰寖鍥村唴鍒欑敓闀 + { + // matDst.at(ptGrowing.y, ptGrowing.x) = 255; + temp_vcGrowPt_size++; + temp_vcGrowPt.push_back(ptGrowing); //灏嗕笅涓涓敓闀跨偣鍘嬪叆鏍堜腑 + } + } + else { + temp_vcGrowPt_size++; + } + } + //鐩搁偦鐨勭敓闀跨偣涓嶆槸鍗曞悜鐢熼暱锛屽垯鐢熼暱鐐规湁鏁 + if (temp_vcGrowPt_size >= 1) { + mat_cnt++; + // matDst.at(pt.y, pt.x) = 255; + matDst.data[pt.y * w + pt.x] = 255; + vcGrowPt.insert(vcGrowPt.end(), temp_vcGrowPt.begin(), temp_vcGrowPt.end()); + } + } return matDst; -} +} \ No newline at end of file