BinaryClassForB.cs 229 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369
  1. using OpenCvSharp;
  2. using PaintDotNet.Annotation;
  3. using PaintDotNet.Base;
  4. using PaintDotNet.Base.CommTool;
  5. using PaintDotNet.Base.Functionodel;
  6. using PaintDotNet.Base.SettingModel;
  7. using PaintDotNet.Data.Param;
  8. using System;
  9. using System.Collections.Generic;
  10. using System.Drawing;
  11. using System.IO;
  12. using System.Linq;
  13. using System.Windows.Forms;
  14. namespace PaintDotNet
  15. {
  16. class BinaryClassForB
  17. {
  18. private int menuId;
  19. protected static string ParamKey_binaryStyle = "binaryStyle";//二值样式
  20. //protected static string ParamKey_displaygrid = "displaygrid";//显示网格
  21. //protected static string ParamKey_displaysections = "displaysections";//显示截点
  22. /// <summary>
  23. /// 是否针对全图进行二值化操作
  24. /// </summary>
  25. public bool processWholeMat = false;
  26. /// <summary>
  27. /// 是否显示视场
  28. /// </summary>
  29. public Boolean ShowDrawClassView = true;
  30. /// <summary>
  31. /// 调色板
  32. /// </summary>
  33. PaintDotNet.ColorsForm colorsForm1;
  34. /// <summary>
  35. /// 构造工作结构
  36. /// </summary>
  37. private Dictionary<int, DocumentItem> documentItems;
  38. /// <summary>
  39. /// 需要的数据在这里引用
  40. /// </summary>
  41. CustomControl.BinaryControlSmaller bmc;
  42. /// <summary>
  43. /// 需要的数据在这里引用
  44. /// </summary>
  45. CustomControl.BinaryControl bc;
  46. AppWorkspace appWorkspace;
  47. DocumentWorkspaceWindow documentWorkspace;
  48. ListView listView1;
  49. public DedicatedAnalysis.Battery.BatteryCrackBallDialog parent { get; set; }
  50. //二次球与单晶
  51. public DedicatedAnalysis.Battery.BatteryBallAndCrystalDialog parentCrystal { get; set; }
  52. //单晶
  53. public DedicatedAnalysis.Battery.BatteryCrystalDialog parentSinglCrystal { get; set; }
  54. //单晶
  55. public DedicatedAnalysis.Battery.BatteryPrimaryDialog parentPrimary { get; set; }
  56. /// <summary>
  57. /// 是否要调用二值化的算法
  58. /// </summary>
  59. private bool toApplyBinary = true;
  60. /// <summary>
  61. /// 处理程序
  62. /// </summary>
  63. private ParamObject action = new Data.Action.Action0001();
  64. /// <summary>
  65. /// 二值参数配置值(当前图片)
  66. /// </summary>
  67. private BinaryExtractionModel binaryExtractionModel;
  68. /// <summary>
  69. /// 二值参数是否进行全部应用,用于更新图片二值化效果,默认为false
  70. /// </summary>
  71. private Dictionary<string, bool> binaryModelFlag = new Dictionary<string, bool>();
  72. /// <summary>
  73. /// 二值参数配置值(全部图片的)
  74. /// </summary>
  75. private Dictionary<string, BinaryExtractionModel> binaryModelDict = new Dictionary<string, BinaryExtractionModel>();
  76. /// <summary>
  77. /// 二值(备份全部图片)
  78. /// </summary>
  79. private Dictionary<string, Mat> binaryData1Dict = new Dictionary<string, Mat>();
  80. /// <summary>
  81. /// 相0的图片,处理多视场使用
  82. /// </summary>
  83. public Mat PhaseModels0Mat;
  84. /// <summary>
  85. /// 辅助线集成
  86. /// </summary>
  87. public PaintDotNet.DedicatedAnalysis.GrainSizeStandard.IntegrationClass.GrainSizeGuideClass guideClass;
  88. public ComboBox comboBox1;
  89. public static Mat dstBinary;
  90. //最大轮廓
  91. public OpenCvSharp.Point[] maxContour = new OpenCvSharp.Point[] { };
  92. //中心点
  93. public OpenCvSharp.Point center = new OpenCvSharp.Point();
  94. //指定圆心
  95. public OpenCvSharp.Point SetCenter = new OpenCvSharp.Point();
  96. double maxArea = 0;
  97. //半径
  98. public int r = 0;
  99. //半径
  100. public int R = 0;
  101. //同心圆数
  102. public int CilCount = 0;
  103. /// 存储轮廓集合
  104. private List<List<PointF>> lineList = new List<List<PointF>>();
  105. /// 存储添加孔隙集合
  106. private List<List<PointF>> kongLineList = new List<List<PointF>>();
  107. /// 存储删除孔隙集合
  108. private List<PointF> delLineList = new List<PointF>();
  109. /// 存储轮廓集合
  110. private List<List<PointF>> lineList_ball = new List<List<PointF>>();
  111. /// 存储开裂球
  112. private List<PointF> kailie_ball = new List<PointF>();
  113. /// 存储普通球
  114. private List<PointF> putong_ball = new List<PointF>();
  115. //存储选择球
  116. private PointF selectPointFs = new PointF();
  117. //处理后画过轮廓的截面孔隙图
  118. private Mat LunkMat = new Mat();
  119. //处理后的单晶图片
  120. private Bitmap bitDJ;
  121. //模块编号:1开裂球,2单晶,3二次球与单晶
  122. public int imageType { set; get; }
  123. //单晶尺寸
  124. public double pointsize { set; get; }
  125. //边界
  126. public int border { set; get; }
  127. //长宽比
  128. public double HW { set; get; }
  129. //面积率
  130. public double AreaRatio { set; get; }
  131. //底边区域
  132. public int borderBottom { set; get; }
  133. //保留小数位数
  134. public int numDecimals { set; get; }
  135. //筛选条件
  136. public int CheckState { set; get; }
  137. //是否画测距
  138. public bool isDis = false;
  139. //是否画矩形
  140. public bool isJu = false;
  141. /// <summary>
  142. /// 单位标尺
  143. /// </summary>
  144. public double unitLength = 1;
  145. //测量区域
  146. public List<OpenCvSharp.Point> Contour { set; get; }
  147. //提示框内容
  148. public string tipString = "";
  149. /// <summary>
  150. /// 公开的事件,每次二值化之后需要的计算事件写在这里
  151. /// </summary>
  152. public event EventHandler BinaryImplFinishAction;
  153. private void OnBinaryImplFinishAction()
  154. {
  155. if (BinaryImplFinishAction != null)
  156. {
  157. BinaryImplFinishAction(this, new EventArgs());
  158. }
  159. }
  160. public BinaryClassForB(int menuId)
  161. {
  162. this.menuId = menuId;
  163. }
  164. public void InitBinaryControlEvent()
  165. {
  166. if (bmc != null)
  167. {
  168. bmc.InitBinaryControlEvent();
  169. bmc.BinaryGetParamAction += new EventHandler(this.bcBinaryGetParamAction);
  170. bmc.AutoThresClickAction += new EventHandler(this.bcAutoThresClickAction);
  171. bmc.InverseClickAction += new EventHandler(this.bcBinaryGetParamAction);
  172. bmc.InverseClickAction += new EventHandler(this.bcApplyButtonImplAction);
  173. bmc.RadioButton1ChangedAction += new EventHandler(this.bcBinaryGetParamAction);
  174. bmc.RadioButton2ChangedAction += new EventHandler(this.bcBinaryGetParamAction);
  175. bmc.ApplyButtonImplAction += new EventHandler(this.bcApplyButtonImplAction);
  176. bmc.BinaryCheckedChangedAction += new EventHandler(this.bcBinaryCheckedChanged);
  177. bmc.OriginCheckedChangedAction += new EventHandler(this.bcOriginCheckedChanged);
  178. bmc.BinaryEditClickAction += new EventHandler(this.bcBinaryEditClickAction);
  179. bmc.PanelColorClickAction += new EventHandler(this.bcPanelColorClickAction);//初始化颜色点击事件
  180. return;
  181. }
  182. if (bc == null)
  183. return;
  184. bc.InitBinaryControlEvent();
  185. bc.BinaryGetParamAction += new EventHandler(this.bcBinaryGetParamAction);
  186. bc.AutoThresClickAction += new EventHandler(this.bcAutoThresClickAction);
  187. bc.InverseClickAction += new EventHandler(this.bcBinaryGetParamAction);
  188. bc.InverseClickAction += new EventHandler(this.bcApplyButtonImplAction);
  189. bc.RadioButton1ChangedAction += new EventHandler(this.bcBinaryGetParamAction);
  190. bc.RadioButton2ChangedAction += new EventHandler(this.bcBinaryGetParamAction);
  191. bc.ApplyButtonImplAction += new EventHandler(this.bcApplyButtonImplAction);
  192. bc.BinaryCheckedChangedAction += new EventHandler(this.bcBinaryCheckedChanged);
  193. bc.OriginCheckedChangedAction += new EventHandler(this.bcOriginCheckedChanged);
  194. bc.BinaryEditClickAction += new EventHandler(this.bcBinaryEditClickAction);
  195. bc.PanelColorClickAction += new EventHandler(this.bcPanelColorClickAction);//初始化颜色点击事件
  196. }
  197. /// <summary>
  198. /// 相颜色点击事件
  199. /// </summary>
  200. /// <param name="sender"></param>
  201. /// <param name="e"></param>
  202. private void bcPanelColorClickAction(object sender, EventArgs e)
  203. {
  204. this.colorsForm1.UserPrimaryColor = ColorBgra.FromColor(bmc != null ? bmc.BinaryBackColor : bc.BinaryBackColor);
  205. this.colorsForm1.ShowDialog();
  206. }
  207. /// <summary>
  208. /// 二值筛选
  209. /// </summary>
  210. /// <param name="sender"></param>
  211. /// <param name="e"></param>
  212. private void bcBinaryEditClickAction(object sender, EventArgs e)
  213. {
  214. if (this.documentWorkspace.PhaseModels[0].mat == null)
  215. {
  216. MessageBox.Show(PdnResources.GetString("Menu.Pleaseperonfirst.text"));
  217. return;
  218. }
  219. PaintDotNet.DedicatedAnalysis.GrainSizeStandard.IntegrationClass.GrainBinaryBoundaryEditingDialog boundaryEditingDialog = new PaintDotNet.DedicatedAnalysis.GrainSizeStandard.IntegrationClass.GrainBinaryBoundaryEditingDialog(this.appWorkspace, this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index, bmc != null ? bmc.BinaryBackColor : bc.BinaryBackColor
  220. , this.documentWorkspace.PhaseModels[0].mat.Clone(), ShowDrawClassView, this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].GetRuler(MeasurementUnit.Micron));
  221. ////1013###19326 晶粒度的晶界编辑页面,需要把辅助线带过去(客户编辑只处理辅助线位置的晶界)
  222. if (this.guideClass != null && this.comboBox1 != null && this.comboBox1.SelectedItem != null)
  223. {
  224. boundaryEditingDialog.GuideClass = this.guideClass;
  225. boundaryEditingDialog.SelectedItem = this.comboBox1.SelectedItem;
  226. }
  227. if (boundaryEditingDialog.ShowDialog() == DialogResult.OK)
  228. {
  229. this.documentWorkspace.PhaseModels[0].mat = boundaryEditingDialog.PhaseMat.Clone();
  230. OnBinaryImplFinishAction();
  231. }
  232. }
  233. /// <summary>
  234. /// 显示原图勾选改变事件
  235. /// </summary>
  236. /// <param name="sender"></param>
  237. /// <param name="e"></param>
  238. private void bcOriginCheckedChanged(object sender, EventArgs e)
  239. {
  240. if (bc == null && bmc == null)
  241. return;
  242. int BinaryCheckFlag = 0;
  243. if (bmc != null ? bmc.OriginChecked : bc.OriginChecked)
  244. BinaryCheckFlag += 1;
  245. if (bmc != null ? bmc.BinaryChecked : bc.BinaryChecked)
  246. BinaryCheckFlag += 2;
  247. this.binaryExtractionModel.BinaryCheckFlag = BinaryCheckFlag;
  248. }
  249. /// <summary>
  250. /// 二值化勾选改变事件
  251. /// </summary>
  252. /// <param name="sender"></param>
  253. /// <param name="e"></param>
  254. private void bcBinaryCheckedChanged(object sender, EventArgs e)
  255. {
  256. if (bc == null && bmc == null)
  257. return;
  258. int BinaryCheckFlag = 0;
  259. if (bmc != null ? bmc.OriginChecked : bc.OriginChecked)
  260. BinaryCheckFlag += 1;
  261. if (bmc != null ? bmc.BinaryChecked : bc.BinaryChecked)
  262. BinaryCheckFlag += 2;
  263. this.binaryExtractionModel.BinaryCheckFlag = BinaryCheckFlag;
  264. if ((bmc != null ? bmc.BinaryChecked : bc.BinaryChecked) && !(bmc != null ? bmc.OriginChecked : bc.OriginChecked))
  265. {
  266. this.documentWorkspace.PhaseModels[0].choise = true;
  267. }
  268. else
  269. {
  270. this.documentWorkspace.PhaseModels[0].choise = false;
  271. }
  272. if (toApplyBinary)
  273. this.applyButtonImpl();
  274. else
  275. OnBinaryImplFinishAction();
  276. toApplyBinary = true;
  277. if (this.listView1.FocusedItem == null || !(bmc != null ? bmc.BinaryChecked : bc.BinaryChecked))
  278. this.documentWorkspace.Refresh();
  279. }
  280. /// <summary>
  281. /// 自动阈值
  282. /// </summary>
  283. /// <param name="sender"></param>
  284. /// <param name="e"></param>
  285. public void bcAutoThresClickAction(object sender, EventArgs e)
  286. {
  287. if (bc == null && bmc == null)
  288. return;
  289. Bitmap bitmap = null;
  290. if (listView1.FocusedItem != null || this.listView1.SelectedItems != null && this.listView1.SelectedItems.Count > 0)
  291. bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
  292. if (bitmap != null)
  293. {
  294. //先计算阈值
  295. Mat mat = OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap);
  296. Mat gray = mat.CvtColor(ColorConversionCodes.BGR2GRAY);
  297. double otsu = Cv2.Threshold(gray, gray, 0, 255, ThresholdTypes.Triangle/*.Otsu*/);
  298. if (otsu <= 10 || otsu >= 245)
  299. {
  300. otsu = Cv2.Threshold(mat.CvtColor(ColorConversionCodes.BGR2GRAY), gray, 0, 255, ThresholdTypes.Otsu);//.Triangle
  301. }
  302. //如果当前是两个区间,则需要重新计算一次
  303. if (this.ColorInterval == 2)
  304. {
  305. if (bmc != null)
  306. bmc.OnInverseClickAction();
  307. else
  308. bc.OnInverseClickAction();
  309. this.ColorInterval = (bmc != null ? bmc.getInverseStyle() : bc.getInverseStyle());
  310. }
  311. else
  312. {
  313. if (bmc != null)
  314. bmc.setInverseStyle(1);
  315. else
  316. bc.setInverseStyle(1);
  317. }
  318. //给控件赋值
  319. if (bmc != null)
  320. bmc.scope1Start = 0;
  321. else
  322. bc.scope1Start = 0;
  323. if (bmc != null)
  324. bmc.scope1End = otsu;
  325. else
  326. bc.scope1End = otsu;
  327. //处理直方图
  328. if (bmc != null)
  329. bmc.UpdateVerticalBarWithOneScope(0, Convert.ToInt32(bmc.scope1End));
  330. else
  331. bc.UpdateVerticalBarWithOneScope(0, Convert.ToInt32(bc.scope1End));
  332. mat.Dispose();
  333. GC.Collect();
  334. this.bcApplyButtonImplAction(sender, e);
  335. }
  336. else
  337. {
  338. MessageBox.Show(PdnResources.GetString("Menu.Pleaseselectapicturefirst.text"));
  339. }
  340. }
  341. /// <summary>
  342. /// 执行读取参数的事件
  343. /// </summary>
  344. /// <param name="sender"></param>
  345. /// <param name="e"></param>
  346. private void bcBinaryGetParamAction(object sender, EventArgs e)
  347. {
  348. if (bc == null && bmc == null)
  349. return;
  350. this.binaryExtractionModel.ColorInterval = (bmc != null ? bmc.getInverseStyle() : bc.getInverseStyle());//###
  351. this.binaryExtractionModel.BinaryStyle = (bmc != null ? bmc.BinaryStyle : bc.BinaryStyle);
  352. this.binaryExtractionModel.ColorOneStart = (int)(bmc != null ? bmc.scope1Start : bc.scope1Start);
  353. this.binaryExtractionModel.ColorOneEnd = (int)(bmc != null ? bmc.scope1End : bc.scope1End);
  354. this.binaryExtractionModel.ColorTwoStart = (int)(bmc != null ? bmc.scope2Start : bc.scope2Start);
  355. this.binaryExtractionModel.ColorTwoEnd = (int)(bmc != null ? bmc.scope2End : bc.scope2End);
  356. this.binaryExtractionModel.ColorThreeStart = (int)(bmc != null ? bmc.scope3Start : bc.scope3Start);
  357. this.binaryExtractionModel.ColorThreeEnd = (int)(bmc != null ? bmc.scope3End : bc.scope3End);
  358. this.initParamsToAction();
  359. }
  360. /// <summary>
  361. /// 获取相的工作结构
  362. /// </summary>
  363. /// <param name="index">指明获取第几个相的工作结构</param>
  364. /// <returns></returns>
  365. public List<PhaseModel> getPhaseModels(int index)
  366. {
  367. return this.documentItems[index].phaseModels;
  368. }
  369. /// <summary>
  370. /// ListView图片选择改变事件
  371. /// </summary>
  372. /// <param name="bitmap">选择改变后的图片</param>
  373. public void listView1_SelectedIndexChanged(Bitmap bitmap, string imagesKey = null)
  374. {
  375. Document document = Document.FromImage(bitmap);
  376. this.documentWorkspace.Document = document;
  377. this.documentWorkspace.Visible = true;
  378. this.documentWorkspace.GraphicsList = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].GraphicsList;
  379. this.documentWorkspace.PhaseModels = new List<PhaseModel>();
  380. this.documentWorkspace.PhaseModels.AddRange(this.getPhaseModels(this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index));
  381. LunkMat = null;
  382. if (imageType != 4)
  383. {
  384. this.applyButtonImpl();
  385. }
  386. if (imagesKey != null && binaryModelFlag.ContainsKey(imagesKey)/*用于更新图片二值化效果*/)
  387. {
  388. this.documentWorkspace.PhaseModels[0].choise = (this.binaryExtractionModel.BinaryCheckFlag == 2);// (bmc != null ? bmc.BinaryChecked : bc.BinaryChecked);
  389. binaryModelFlag[imagesKey] = false;
  390. if (bmc != null)
  391. bmc.BinaryChecked = this.documentWorkspace.PhaseModels[0].choise || (this.binaryExtractionModel.BinaryCheckFlag > 1);
  392. else
  393. bc.BinaryChecked = this.documentWorkspace.PhaseModels[0].choise || (this.binaryExtractionModel.BinaryCheckFlag > 1);
  394. }
  395. else if ((bc != null || bmc != null) && !this.documentWorkspace.PhaseModels[0].choise
  396. && (this.binaryExtractionModel.BinaryCheckFlag <= 1))
  397. if (bmc != null)
  398. bmc.BinaryChecked = false;
  399. else
  400. bc.BinaryChecked = false;
  401. if (imagesKey != null)
  402. {
  403. if (this.binaryExtractionModel.BinaryCheckFlag % 2 == 1)
  404. {
  405. if (bmc != null)
  406. bmc.OriginChecked = true;
  407. else
  408. bc.OriginChecked = true;
  409. }
  410. else
  411. {
  412. if (bmc != null)
  413. bmc.OriginChecked = false;
  414. else
  415. bc.OriginChecked = false;
  416. }
  417. }
  418. //显示直方图
  419. if (bc != null || bmc != null)
  420. if (bmc != null)
  421. bmc.CreateHistogram(bitmap, true, 339, 130, 0);
  422. else
  423. bc.CreateHistogram(bitmap, true, 339, 130, 0);
  424. this.RefreshHistogramControl1Values();
  425. }
  426. /// <summary>
  427. /// 构造相的工作结构
  428. /// </summary>
  429. /// <param name="phaseNames">相的命名,如果只有二值则只传PdnResources.GetString("Menu.BinaryAction.BinaryExtraction.Text")即可,没有特殊情况命名第一个相为PdnResources.GetString("Menu.BinaryAction.BinaryExtraction.Text")</param>
  430. /// <param name="bmc"></param>
  431. /// <param name="appWorkspace"></param>
  432. /// <param name="documentWorkspace"></param>
  433. public void createDocumentItemsSmaller(string[] phaseNames, CustomControl.BinaryControlSmaller bmc, AppWorkspace appWorkspace
  434. , DocumentWorkspaceWindow documentWorkspace, ListView listView1)
  435. {
  436. this.bmc = bmc;
  437. this.appWorkspace = appWorkspace;
  438. this.documentWorkspace = documentWorkspace;
  439. this.listView1 = listView1;
  440. this.initParams();
  441. for (int i = 0; i < phaseNames.Length; i++)
  442. {
  443. PhaseModel model = new PhaseModel();
  444. model.choise = true;
  445. model.mat = null;
  446. model.color = (i == 0 && bmc != null) ? bmc.BinaryBackColor.ToArgb() : Color.Green.ToArgb();//###
  447. model.position = documentWorkspace.PhaseModels.Count + 1;
  448. model.name = phaseNames[i];
  449. documentWorkspace.PhaseModels.Add(model);
  450. }
  451. this.documentItems = new Dictionary<int, DocumentItem>();
  452. // 构造工作结构
  453. for (int i = 0; i < appWorkspace.DocumentWorkspaces.Length; i++)
  454. {
  455. Bitmap bitmap = appWorkspace.DocumentWorkspaces[i].CompositionSurface.CreateAliasedBitmap();
  456. GraphicsList graphicsList = new GraphicsList();
  457. for (int j = 0; j < appWorkspace.DocumentWorkspaces[i].GraphicsList.Count; j++)
  458. {
  459. graphicsList.Add(appWorkspace.DocumentWorkspaces[i].GraphicsList[j]);
  460. }
  461. List<PhaseModel> phaseModels = new List<PhaseModel>();
  462. for (int j = 0; j < phaseNames.Length; j++)
  463. {
  464. //二值化相关
  465. if (j == 0)
  466. {
  467. PhaseModel analysisModel = appWorkspace.DocumentWorkspaces[i].AnalysisPhaseModel;
  468. if (analysisModel == null)
  469. {
  470. PhaseModel model = new PhaseModel();
  471. model.choise = true;
  472. model.mat = null;
  473. model.color = bmc != null ? bmc.BinaryBackColor.ToArgb() : Color.Green.ToArgb();
  474. model.position = phaseModels.Count + 1;
  475. model.name = phaseNames[j];
  476. phaseModels.Add(model);
  477. }
  478. else
  479. phaseModels.Add(analysisModel);
  480. }
  481. else
  482. {
  483. PhaseModel model = new PhaseModel();
  484. model.choise = true;
  485. model.mat = null;
  486. model.color = Color.Green/*panel2.BackColor*/.ToArgb();//###
  487. model.position = phaseModels.Count + 1;
  488. model.name = phaseNames[j];
  489. phaseModels.Add(model);
  490. }
  491. }
  492. this.documentItems.Add(i, new DocumentItem(bitmap, graphicsList, phaseModels));
  493. }
  494. //
  495. //调色板
  496. //
  497. this.colorsForm1 = new ColorsForm();
  498. this.colorsForm1.StartPosition = FormStartPosition.CenterScreen;
  499. this.colorsForm1.setSaveBtn_Click(new System.EventHandler(this.colorsForm1Changed));
  500. this.InitParameterToControl();//###
  501. if (this.binaryExtractionModel != null)
  502. this.applyButtonImpl();
  503. this.InitBinaryControlEvent();
  504. }
  505. /// <summary>
  506. /// 无视场执行运算
  507. /// </summary>
  508. public OpenCvSharp.Mat PerformProcess(OpenCvSharp.Mat src) { return action.PerformProcess(src); }
  509. /// <summary>
  510. /// 无视场执行运算
  511. /// </summary>
  512. public OpenCvSharp.Mat PerformProcess(OpenCvSharp.Mat src, Base.Functionodel.PhaseModel phaseModel, System.Drawing.Point point) { return action.PerformProcess(src, phaseModel, point); }
  513. /// <summary>
  514. /// 无视场执行运算
  515. /// </summary>
  516. public OpenCvSharp.Mat PerformProcessGetdata(OpenCvSharp.Mat src, out List<List<int>> data) { return action.PerformProcessGetdata(src, out data); }
  517. /// 无视场执行运算
  518. /// </summary>
  519. public OpenCvSharp.Mat PerformProcessGetdata(OpenCvSharp.Mat src, OpenCvSharp.Mat source, out List<List<int>> data) { return action.PerformProcessGetdata(src, source, out data); }
  520. /// <summary>
  521. /// 多视场执行运算
  522. /// </summary>
  523. /// <param name="src">视场mat</param>
  524. /// <param name="mat">原图mat</param>
  525. /// <returns></returns>
  526. public OpenCvSharp.Mat PerformProcess(OpenCvSharp.Mat src, OpenCvSharp.Mat mat) { return action.PerformProcess(src, mat); }
  527. public int ColorInterval
  528. {
  529. get
  530. {
  531. return this.binaryExtractionModel.ColorInterval;
  532. }
  533. set
  534. {
  535. this.binaryExtractionModel.ColorInterval = value;
  536. }
  537. }
  538. private void colorsForm1Changed(object sender, EventArgs e)
  539. {
  540. Color color = this.colorsForm1.UserPrimaryColor.ToColor();
  541. this.SetBinaryBackColor(color);//改变参数配置的相颜色
  542. this.colorsForm1.Close();
  543. }
  544. /// <summary>
  545. /// 把参数的值设置到控件上
  546. /// </summary>
  547. public void InitParameterToControl()
  548. {
  549. if (this.binaryExtractionModel != null)
  550. {
  551. if (bc != null || bmc != null)
  552. {
  553. if (this.binaryExtractionModel.BinaryCheckFlag > 1)
  554. {
  555. if (bmc != null)
  556. bmc.BinaryChecked = true;
  557. else
  558. bc.BinaryChecked = true;
  559. }
  560. if (this.binaryExtractionModel.BinaryCheckFlag % 2 == 1)
  561. {
  562. if (bmc != null)
  563. bmc.OriginChecked = true;
  564. else
  565. bc.OriginChecked = true;
  566. }
  567. if (imageType == 2)
  568. {
  569. return;
  570. }
  571. //阈值相关
  572. //1个颜色区间还是2个
  573. if (bmc != null)
  574. bmc.setInverseStyle((this.binaryExtractionModel.ColorInterval == 1) ? 1 : 2);
  575. else
  576. bc.setInverseStyle((this.binaryExtractionModel.ColorInterval == 1) ? 1 : 2);
  577. //删除事件
  578. if (bmc != null)
  579. bmc.DeleteEventHandler();
  580. else
  581. bc.DeleteEventHandler();
  582. if (imageType == 2)
  583. {
  584. return;
  585. }
  586. if (bmc != null)
  587. bmc.scope1End = this.binaryExtractionModel.ColorOneEnd;
  588. else
  589. bc.scope1End = this.binaryExtractionModel.ColorOneEnd;
  590. if (bmc != null)
  591. bmc.scope1Start = this.binaryExtractionModel.ColorOneStart;
  592. else
  593. bc.scope1Start = this.binaryExtractionModel.ColorOneStart;
  594. if (bmc != null)
  595. bmc.scope2End = this.binaryExtractionModel.ColorTwoEnd;
  596. else
  597. bc.scope2End = this.binaryExtractionModel.ColorTwoEnd;
  598. if (bmc != null)
  599. bmc.scope2Start = this.binaryExtractionModel.ColorTwoStart;
  600. else
  601. bc.scope2Start = this.binaryExtractionModel.ColorTwoStart;
  602. if (bmc != null)
  603. bmc.scope3End = this.binaryExtractionModel.ColorThreeEnd;
  604. else
  605. bc.scope3End = this.binaryExtractionModel.ColorThreeEnd;
  606. if (bmc != null)
  607. bmc.scope3Start = this.binaryExtractionModel.ColorThreeStart;
  608. else
  609. bc.scope3Start = this.binaryExtractionModel.ColorThreeStart;
  610. if (bmc != null)
  611. bmc.BinaryStyle = this.binaryExtractionModel.BinaryStyle;
  612. else
  613. bc.BinaryStyle = this.binaryExtractionModel.BinaryStyle;
  614. if (bmc != null)
  615. bmc.BinaryBackColor = Color.FromArgb(this.binaryExtractionModel.PhaseColor);
  616. else
  617. bc.BinaryBackColor = Color.FromArgb(this.binaryExtractionModel.PhaseColor);
  618. //添加事件
  619. if (bmc != null)
  620. bmc.AddEventHandler();
  621. else
  622. bc.AddEventHandler();
  623. if (bmc != null)
  624. bmc.InitParameterToControl();
  625. else
  626. bc.InitParameterToControl();
  627. }
  628. }
  629. }
  630. /// <summary>
  631. /// 更新显示直方图的数据
  632. /// </summary>
  633. public void RefreshHistogramControl1Values()
  634. {
  635. ////显示直方图
  636. //if (bc != null || bmc != null)
  637. // if (bmc != null)
  638. // bmc.CreateHistogram(bitmap, true, 339, 130, 0);
  639. // else
  640. // bc.CreateHistogram(bitmap, true, 339, 130, 0);
  641. if (bmc != null)
  642. bmc.InitParameterToControl(this.binaryExtractionModel.ColorInterval);
  643. else if (bc != null)
  644. bc.InitParameterToControl(this.binaryExtractionModel.ColorInterval);
  645. }
  646. public void SetBinaryBackColor(Color color)
  647. {
  648. if (bmc != null)
  649. bmc.BinaryBackColor = color;//设置panel背景
  650. else
  651. bc.BinaryBackColor = color;//设置panel背景
  652. this.binaryExtractionModel.PhaseColor = color.ToArgb();
  653. //###
  654. foreach (Args args in action.Lists)
  655. {
  656. if (args.Key == "phaseColor")
  657. {
  658. args.Value = color.ToArgb();//this.binaryExtractionModel.PhaseColor
  659. break;
  660. }
  661. }
  662. this.applyButtonImpl();
  663. }
  664. /// <summary>
  665. /// 保证二值化颜色赋值到action
  666. /// </summary>
  667. public void loadParams()
  668. {
  669. if (bc == null && bmc == null)
  670. return;
  671. foreach (Args args in action.Lists)
  672. {
  673. switch (args.Key)
  674. {
  675. case "scope1"://不反选时候的范围
  676. if (bmc != null)
  677. bmc.ScopeValue1ChangedAction += new EventHandler(((DecimalScope)args).numberScope_ValueChanged);
  678. else
  679. bc.ScopeValue1ChangedAction += new EventHandler(((DecimalScope)args).numberScope_ValueChanged);
  680. break;
  681. case "scope2"://反选时候的范围1
  682. if (bmc != null)
  683. bmc.ScopeValue2ChangedAction += new EventHandler(((DecimalScope)args).numberScope_ValueChanged);
  684. else
  685. bc.ScopeValue2ChangedAction += new EventHandler(((DecimalScope)args).numberScope_ValueChanged);
  686. break;
  687. case "scope3"://反选时候的范围2
  688. if (bmc != null)
  689. bmc.ScopeValue3ChangedAction += new EventHandler(((DecimalScope)args).numberScope_ValueChanged);
  690. else
  691. bc.ScopeValue3ChangedAction += new EventHandler(((DecimalScope)args).numberScope_ValueChanged);
  692. break;
  693. case "phaseColor":
  694. args.Value = this.binaryExtractionModel.PhaseColor;
  695. break;
  696. default:
  697. break;
  698. }
  699. }
  700. }
  701. /// <summary>
  702. /// 执行二值方法的事件
  703. /// </summary>
  704. /// <param name="sender"></param>
  705. /// <param name="e"></param>
  706. private void bcApplyButtonImplAction(object sender, EventArgs e)
  707. {
  708. this.applyButtonImpl(/*bitmap*/);
  709. }
  710. private bool cornerHarris_demo()
  711. {
  712. string subPath = System.Configuration.ConfigurationManager.AppSettings["TempPath"];
  713. string newbitmap = subPath + "\\mask.jpg";
  714. Bitmap bmOld = new Bitmap(newbitmap);
  715. int iwidth = bmOld.Width;
  716. int iHeight = bmOld.Height;
  717. Bitmap newBmp = new Bitmap(bmOld);
  718. Bitmap bitmap1 = newBmp.Clone(new Rectangle(0, 0, iwidth, iHeight), System.Drawing.Imaging.PixelFormat.Format32bppArgb);
  719. bitDJ = bitmap1;
  720. Mat src = OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap1);
  721. Mat gray = new Mat();
  722. Cv2.CvtColor(src, gray, ColorConversionCodes.BGRA2GRAY);
  723. using (new Window("ss", WindowMode.Normal, gray))
  724. {
  725. Cv2.WaitKey(0);
  726. }
  727. OpenCvSharp.Point[][] contours;
  728. HierarchyIndex[] hierarchy;
  729. Cv2.FindContours(gray, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone, null);
  730. for (int h = 0; h < contours.Length; h++)
  731. {
  732. if (contours[h].Length < 20)
  733. {
  734. continue;
  735. }
  736. Mat src_gray = Mat.Zeros(src.Size(), MatType.CV_8UC1);
  737. src_gray.DrawContours(contours, h, new Scalar(255), -1);
  738. //src_gray.Resize(new OpenCvSharp.Size(src_gray.Width * 3, src_gray.Height * 3));
  739. Mat dst = src_gray.Clone();
  740. using (new Window("s1", WindowMode.Normal, dst))
  741. {
  742. Cv2.WaitKey(0);
  743. }
  744. // Cv2.MedianBlur(src_gray, src_gray, 9);
  745. Point2f[] cornersPoint = Cv2.GoodFeaturesToTrack(src_gray, 100, 0.01, 30, new Mat(), 3, false, 0.04);
  746. foreach (var item in cornersPoint)
  747. {
  748. Cv2.Circle(dst, Convert.ToInt16(item.X), Convert.ToInt16(item.Y), 10, Scalar.White, 2);
  749. }
  750. using (new Window("ss", WindowMode.Normal, dst))
  751. {
  752. Cv2.WaitKey(0);
  753. }
  754. }
  755. return false;
  756. }
  757. ///// <summary>
  758. ///// 参数改变时,重新处理图像
  759. ///// </summary>
  760. /// <param name="imagesKey">不是当前显示图片的需要传值</param>
  761. /// <param name="analysisPicture">不是当前显示图片的需要传值</param>
  762. /// <param name="bitmap">不带视场处理的需要传值</param>
  763. /// <param name="imageType">模块编号:1开裂球,2单晶,3二次球与单晶,4开裂球</param>
  764. public void applyButtonImpl(string imagesKey = null, int analysisPicture = -1, Bitmap bitmap = null)
  765. {
  766. List<List<int>> data = new List<List<int>>() { };
  767. Mat newMat = new Mat();
  768. ProgressThreadProcClass procClass = new ProgressThreadProcClass();
  769. int itemCount = 100;
  770. ProgressThreadProcClass.IFileTransferProgressEvents progressEvents = new ProgressThreadProcClass.IFileTransferProgressEvents();
  771. switch (imageType)
  772. {
  773. case 2:
  774. #region 单晶
  775. if (listView1.FocusedItem != null || this.listView1.SelectedItems != null && this.listView1.SelectedItems.Count > 0)
  776. {
  777. bool processWholeMat11 = (bitmap != null);
  778. if (bitmap == null)
  779. /*Bitmap */
  780. bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
  781. //cornerHarris_demo();
  782. //判断是否存在视场,如果存在视场,则把视场提取出来,进行处理//可能会带视场//########################
  783. DocumentView documentWorkspace = this.documentWorkspace;
  784. // string name = this.listView1.FocusedItem.Name.Split('.')[0];
  785. string name = "inputImg";
  786. if (analysisPicture == -1)
  787. {
  788. action.Lists.Add(new Args() { Key = "imageType", Value = 12 });
  789. action.Lists.Add(new Args() { Key = "SelPointFs", Value = -1 });
  790. action.Lists.Add(new Args() { Key = "pointsize", Value = pointsize });
  791. action.Lists.Add(new Args() { Key = "borderBottom", Value = borderBottom });
  792. action.Lists.Add(new Args() { Key = "Micron", Value = unitLength });
  793. action.Lists.Add(new Args() { Key = "border", Value = border });
  794. action.Lists.Add(new Args() { Key = "HW", Value = HW });
  795. action.Lists.Add(new Args() { Key = "AreaRatio", Value = AreaRatio });
  796. action.Lists.Add(new Args() { Key = "DelPointFs", Value = null });
  797. action.Lists.Add(new Args() { Key = "AddPontins", Value = null });
  798. action.Lists.Add(new Args() { Key = "Contour", Value = null });
  799. action.Lists.Add(new Args() { Key = "isDis", Value = isDis });
  800. action.Lists.Add(new Args() { Key = "isJu", Value = isJu });
  801. System.Threading.ThreadStart copyThreadProcCrystal =
  802. delegate ()
  803. {
  804. try
  805. {
  806. //检查是否存在文件夹
  807. //string subPath = @"C:\MetisTemp";
  808. string subPath = System.Configuration.ConfigurationManager.AppSettings["TempPath"];
  809. if (false == System.IO.Directory.Exists(subPath))
  810. {
  811. //创建pic文件夹
  812. System.IO.Directory.CreateDirectory(subPath);
  813. }
  814. else
  815. {
  816. DirectoryInfo di = new DirectoryInfo(subPath);
  817. FileSystemInfo[] fileinfo = di.GetFileSystemInfos();
  818. try
  819. {
  820. foreach (FileSystemInfo item in fileinfo)
  821. {
  822. //if(item.Name!= "mask.jpg")
  823. item.Delete();
  824. // File.Delete(item.FullName);
  825. }
  826. }
  827. catch (Exception e)
  828. {
  829. }
  830. }
  831. string savepath = subPath + "\\" + name + ".png";
  832. string isCpu = System.Configuration.ConfigurationManager.AppSettings["CpuORGpu"];
  833. bitmap.Save(savepath, System.Drawing.Imaging.ImageFormat.Png);
  834. //1金相/2析出物 0是cpu,1是GPU 尺寸0是自动算
  835. string sArguments = subPath + " " + name + ".png 2 " + isCpu + " 0";
  836. //string sArguments = "-filepath "+subPath + "\\" + name + ".png --useGpu " + isCpu + " --diameter 30,20";
  837. System.Diagnostics.Process p = new System.Diagnostics.Process();
  838. //p.StartInfo.FileName = System.Environment.CurrentDirectory + "\\crystal\\crystal.exe";
  839. p.StartInfo.FileName = System.Environment.CurrentDirectory + "\\educt\\educt.exe";
  840. //p.StartInfo.FileName = System.Environment.CurrentDirectory + "\\granule_engine_3G\\granule_engine.exe";
  841. p.StartInfo.Arguments = sArguments;//python命令的参数
  842. p.StartInfo.UseShellExecute = false;
  843. p.StartInfo.RedirectStandardInput = true;
  844. p.StartInfo.RedirectStandardOutput = true;
  845. p.StartInfo.RedirectStandardError = true;
  846. p.StartInfo.CreateNoWindow = true;
  847. string strOutput = null;
  848. p.Start();
  849. strOutput = p.StandardOutput.ReadToEnd();
  850. p.WaitForExit();
  851. p.Close();
  852. string newbitmap = subPath + "\\mask.jpg";
  853. //Bitmap bmOld = new Bitmap(newbitmap);
  854. //int iwidth = bmOld.Width;
  855. //int iHeight = bmOld.Height;
  856. //Bitmap newBmp = new Bitmap(bmOld);
  857. //Bitmap bitmap1 = newBmp.Clone(new Rectangle(0, 0, iwidth, iHeight), System.Drawing.Imaging.PixelFormat.Format32bppArgb);
  858. //bitDJ = (Bitmap)bitmap1.Clone();
  859. // newMat = this.PerformProcessGetdata(OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap1), out data);
  860. Mat mask = Cv2.ImRead(newbitmap);
  861. newMat = this.PerformProcessGetdata(mask, out data);
  862. if (bmc != null) { bmc.data = data; bmc.isedit = true; }
  863. if (bc != null) { bc.data = data; bc.isedit = true; }
  864. documentWorkspace.PhaseModels[0].mat = newMat;
  865. documentWorkspace.PhaseModels[0].color = (bmc != null ? bmc.BinaryBackColor.ToArgb() : bc.BinaryBackColor.ToArgb());
  866. documentWorkspace.Refresh();
  867. }
  868. catch (Exception e)
  869. {
  870. }
  871. finally
  872. {
  873. progressEvents.EndOperation(OperationResult.Finished);
  874. }
  875. };
  876. if (string.IsNullOrEmpty(tipString))
  877. {
  878. procClass.StartProgressAction(/*currentForm*/parentSinglCrystal, itemCount, copyThreadProcCrystal, progressEvents, null);
  879. }
  880. else
  881. {
  882. procClass.StartProgressAction(/*currentForm*/parentSinglCrystal, itemCount, copyThreadProcCrystal, progressEvents, tipString);
  883. }
  884. }
  885. }
  886. #endregion
  887. break;
  888. case 4:
  889. #region 开裂球
  890. if (bc == null && bmc == null)
  891. return;
  892. //long start = Cv2.GetTickCount();
  893. if (bitmap != null ||
  894. (listView1.FocusedItem != null || this.listView1.SelectedItems != null && this.listView1.SelectedItems.Count > 0) && (bmc != null ? bmc.BinaryChecked : bc.BinaryChecked))
  895. {
  896. bool processWholeMat11 = (bitmap != null);
  897. if (bitmap == null)
  898. /*Bitmap */
  899. bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
  900. action.Lists.Add(new Args() { Key = "imageTypes", Value = 4 });
  901. action.Lists.Add(new Args() { Key = "SelPointFs", Value = -1 });
  902. string name = this.listView1.FocusedItem.Name.Split('.')[0];
  903. System.Threading.ThreadStart copyThreadProc =
  904. delegate ()
  905. {
  906. try
  907. {
  908. #region 人工只能找轮廓
  909. //检查是否存在文件夹
  910. //string subPath = @"C:\MetisTemp";
  911. //string subPath = System.Configuration.ConfigurationManager.AppSettings["TempPath"];
  912. //if (false == System.IO.Directory.Exists(subPath))
  913. //{
  914. // //创建pic文件夹
  915. // System.IO.Directory.CreateDirectory(subPath);
  916. //}
  917. //else
  918. //{
  919. // DirectoryInfo di = new DirectoryInfo(subPath);
  920. // FileSystemInfo[] fileinfo = di.GetFileSystemInfos();
  921. // foreach (FileSystemInfo item in fileinfo)
  922. // {
  923. // item.Delete();
  924. // // File.Delete(item.FullName);
  925. // }
  926. //}
  927. //string savepath = subPath + "\\" + name + ".png";
  928. //bitmap.Save(savepath, System.Drawing.Imaging.ImageFormat.Png);
  929. ////1金相/2析出物 0是cpu1是GPU 尺寸0是自动算
  930. //string sArguments = subPath + " " + name + ".png 1 0 0";
  931. //System.Diagnostics.Process p = new System.Diagnostics.Process();
  932. ////p.StartInfo.FileName = System.Environment.CurrentDirectory + "\\crystal\\crystal.exe";
  933. //p.StartInfo.FileName = System.Environment.CurrentDirectory + "\\educt\\educt.exe";
  934. //p.StartInfo.Arguments = sArguments;//python命令的参数
  935. //p.StartInfo.UseShellExecute = false;
  936. //p.StartInfo.RedirectStandardInput = true;
  937. //p.StartInfo.RedirectStandardOutput = true;
  938. //p.StartInfo.RedirectStandardError = true;
  939. //p.StartInfo.CreateNoWindow = true;
  940. //string strOutput = null;
  941. //p.Start();
  942. //strOutput = p.StandardOutput.ReadToEnd();
  943. //p.WaitForExit();
  944. //p.Close();
  945. //string newbitmap = subPath + "\\mask.jpg";
  946. //Bitmap bmOld = new Bitmap(newbitmap);
  947. //int iwidth = bmOld.Width;
  948. //int iHeight = bmOld.Height;
  949. //Bitmap newBmp = new Bitmap(bmOld);
  950. //Bitmap bitmap1 = newBmp.Clone(new Rectangle(0, 0, iwidth, iHeight), System.Drawing.Imaging.PixelFormat.Format32bppArgb);
  951. //bitDJ = bitmap1;
  952. //Mat pyston = OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap1);
  953. #endregion
  954. #region 分水岭找轮廓
  955. newMat = this.PerformProcessGetdata(OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap), out data);
  956. PhaseModel model = new PhaseModel();
  957. model.color = -14607873;
  958. model.mat = new OpenCvSharp.Mat();
  959. newMat.CopyTo(model.mat);
  960. newMat = this.PerformProcess(newMat, model, new System.Drawing.Point());
  961. LunkMat = newMat.Clone();
  962. action.Lists.Add(new Args() { Key = "imageTypes", Value = 14 });
  963. data.Clear();
  964. #endregion
  965. newMat = this.PerformProcessGetdata(LunkMat, OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap), out data);
  966. }
  967. catch (Exception e)
  968. {
  969. }
  970. finally
  971. {
  972. progressEvents.EndOperation(OperationResult.Finished);
  973. }
  974. };
  975. procClass.StartProgressAction(/*currentForm*/parent, itemCount, copyThreadProc, progressEvents, null);
  976. if (bmc != null) { bmc.data = data; bmc.isedit = true; }
  977. if (bc != null) { bc.data = data; bc.isedit = true; }
  978. documentWorkspace.PhaseModels[0].mat = newMat;
  979. documentWorkspace.PhaseModels[0].color = (bmc != null ? bmc.BinaryBackColor.ToArgb() : bc.BinaryBackColor.ToArgb());
  980. documentWorkspace.Refresh();
  981. }
  982. #endregion
  983. break;
  984. case 3:
  985. #region 二次球与单晶
  986. if (bc == null && bmc == null)
  987. return;
  988. //long start = Cv2.GetTickCount();
  989. if (bitmap != null ||
  990. (listView1.FocusedItem != null || this.listView1.SelectedItems != null && this.listView1.SelectedItems.Count > 0) && (bmc != null ? bmc.BinaryChecked : bc.BinaryChecked))
  991. {
  992. bool processWholeMat11 = (bitmap != null);
  993. if (bitmap == null)
  994. /*Bitmap */
  995. bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
  996. action.Lists.Add(new Args() { Key = "CircleCount", Value = 0 });
  997. action.Lists.Add(new Args() { Key = "imageTypes", Value = 3 });
  998. newMat = this.PerformProcessGetdata(OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap), out data);
  999. if (bmc != null) { bmc.data = data; bmc.isedit = true; }
  1000. if (bc != null) { bc.data = data; bc.isedit = true; }
  1001. documentWorkspace.PhaseModels[0].mat = newMat;
  1002. documentWorkspace.PhaseModels[0].color = (bmc != null ? bmc.BinaryBackColor.ToArgb() : bc.BinaryBackColor.ToArgb());
  1003. documentWorkspace.Refresh();
  1004. }
  1005. #endregion
  1006. break;
  1007. case 1:
  1008. #region 截面孔隙
  1009. if (bc == null && bmc == null)
  1010. return;
  1011. //long start = Cv2.GetTickCount();
  1012. if (bitmap != null ||
  1013. (listView1.FocusedItem != null || this.listView1.SelectedItems != null && this.listView1.SelectedItems.Count > 0) && (bmc != null ? bmc.BinaryChecked : bc.BinaryChecked))
  1014. {
  1015. bool processWholeMat11 = (bitmap != null);
  1016. if (bitmap == null)
  1017. /*Bitmap */
  1018. bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
  1019. //判断是否存在视场,如果存在视场,则把视场提取出来,进行处理//可能会带视场//########################
  1020. DocumentView documentWorkspace = this.documentWorkspace;
  1021. //GetParameter2();
  1022. if (analysisPicture == -1)
  1023. {
  1024. if (LunkMat != null && LunkMat.Rows > 10)
  1025. {
  1026. }
  1027. else
  1028. {
  1029. Mat maptomat = getimage(bitmap);
  1030. LunkMat = maptomat.Clone();
  1031. List<Scalar> colorList = new List<Scalar>() { new Scalar(0, 0, 255, 255), new Scalar(0, 255, 0, 255), new Scalar(0, 255, 255, 255), new Scalar(128, 0, 128, 255), new Scalar(230, 216, 173, 255) };
  1032. double dist = 0;
  1033. double maxdist = 0;
  1034. //InputArray contoursAll = InputArray.Create(maxContour);
  1035. //List<OpenCvSharp.Point> outArr = new List<OpenCvSharp.Point>();
  1036. //OutputArray hull = OutputArray.Create(outArr);
  1037. //Cv2.ConvexHull(contoursAll, hull, true);
  1038. //using (new Window("InputImage", WindowMode.Normal, LunkMat))
  1039. //{
  1040. // Cv2.WaitKey(0);
  1041. //}
  1042. if (CilCount > 1)
  1043. {
  1044. for (int i = 0; i < maptomat.Cols; i = i + 50)
  1045. {
  1046. for (int j = 0; j < maptomat.Rows; j = j + 50)
  1047. {
  1048. OpenCvSharp.Point point = new OpenCvSharp.Point(i, j);
  1049. dist = Cv2.PointPolygonTest(maxContour, point, true);
  1050. if (dist > maxdist)
  1051. {
  1052. maxdist = dist;
  1053. center = point;
  1054. }
  1055. }
  1056. }
  1057. R = Convert.ToInt32(maxdist);
  1058. r = Convert.ToInt32(maxdist) / CilCount;
  1059. }
  1060. SetCenter = center;
  1061. //r = r - 10;
  1062. action.Lists.Add(new Args() { Key = "CircleCount", Value = CilCount });
  1063. action.Lists.Add(new Args() { Key = "CircleR", Value = r });
  1064. action.Lists.Add(new Args() { Key = "Center", Value = center });
  1065. action.Lists.Add(new Args() { Key = "imageType", Value = 1 });
  1066. action.Lists.Add(new Args() { Key = "SelPointFs", Value = -1 });
  1067. action.Lists.Add(new Args() { Key = "DelPointFs", Value = null });
  1068. action.Lists.Add(new Args() { Key = "AddPontins", Value = null });
  1069. }
  1070. newMat = this.PerformProcessGetdata(LunkMat, out data);
  1071. List<int> CircleDate = data[0];
  1072. CircleDate[CircleDate.Count - 1] = Convert.ToInt32(maxArea);
  1073. if (bmc != null) { bmc.data = data; bmc.isedit = true; }
  1074. if (bc != null) { bc.data = data; bc.isedit = true; }
  1075. documentWorkspace.PhaseModels[0].mat = newMat;
  1076. documentWorkspace.PhaseModels[0].color = (bmc != null ? bmc.BinaryBackColor.ToArgb() : bc.BinaryBackColor.ToArgb());
  1077. documentWorkspace.Refresh();
  1078. }
  1079. }
  1080. if (analysisPicture == -1)
  1081. OnBinaryImplFinishAction();
  1082. #endregion
  1083. break;
  1084. case 5:
  1085. #region 隔膜
  1086. if (bc == null && bmc == null)
  1087. return;
  1088. //long start = Cv2.GetTickCount();
  1089. if (bitmap != null ||
  1090. (listView1.FocusedItem != null || this.listView1.SelectedItems != null && this.listView1.SelectedItems.Count > 0) && (bmc != null ? bmc.BinaryChecked : bc.BinaryChecked))
  1091. {
  1092. bool processWholeMat11 = (bitmap != null);
  1093. if (bitmap == null)
  1094. /*Bitmap */
  1095. bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
  1096. // double d = GetRuler();
  1097. //判断是否存在视场,如果存在视场,则把视场提取出来,进行处理//可能会带视场//########################
  1098. DocumentView documentWorkspace = this.documentWorkspace;
  1099. //GetParameter2();
  1100. if (analysisPicture == -1)
  1101. {
  1102. action.Lists.Add(new Args() { Key = "CircleCount", Value = 0 });
  1103. action.Lists.Add(new Args() { Key = "imageType", Value = 5 });
  1104. action.Lists.Add(new Args() { Key = "SelPointFs", Value = -1 });
  1105. newMat = this.PerformProcessGetdata(OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap), out data);
  1106. if (bmc != null) { bmc.data = data; bmc.isedit = true; }
  1107. if (bc != null) { bc.data = data; bc.isedit = true; }
  1108. documentWorkspace.PhaseModels[0].mat = newMat;
  1109. documentWorkspace.PhaseModels[0].color = (bmc != null ? bmc.BinaryBackColor.ToArgb() : bc.BinaryBackColor.ToArgb());
  1110. documentWorkspace.Refresh();
  1111. }
  1112. }
  1113. if (analysisPicture == -1)
  1114. OnBinaryImplFinishAction();
  1115. #endregion
  1116. break;
  1117. case 6:
  1118. #region 前驱截面一次颗粒
  1119. if (bc == null && bmc == null)
  1120. return;
  1121. if (listView1.FocusedItem != null || this.listView1.SelectedItems != null && this.listView1.SelectedItems.Count > 0)
  1122. {
  1123. bool processWholeMat11 = (bitmap != null);
  1124. if (bitmap == null)
  1125. /*Bitmap */
  1126. bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
  1127. //判断是否存在视场,如果存在视场,则把视场提取出来,进行处理//可能会带视场//########################
  1128. DocumentView documentWorkspace = this.documentWorkspace;
  1129. string name = "inputImg";
  1130. double d = documentWorkspace.GetRuler(MeasurementUnit.Micron);
  1131. if (analysisPicture == -1)
  1132. {
  1133. action.Lists.Add(new Args() { Key = "imageType", Value = 12 });
  1134. action.Lists.Add(new Args() { Key = "SelPointFs", Value = -1 });
  1135. action.Lists.Add(new Args() { Key = "pointsize", Value = pointsize });
  1136. action.Lists.Add(new Args() { Key = "Micron", Value = d });
  1137. action.Lists.Add(new Args() { Key = "border", Value = border });
  1138. action.Lists.Add(new Args() { Key = "HW", Value = HW });
  1139. action.Lists.Add(new Args() { Key = "AreaRatio", Value = AreaRatio });
  1140. action.Lists.Add(new Args() { Key = "DelPointFs", Value = null });
  1141. action.Lists.Add(new Args() { Key = "AddPontins", Value = null });
  1142. action.Lists.Add(new Args() { Key = "Contour", Value = null });
  1143. System.Threading.ThreadStart copyThreadProcCrystal =
  1144. delegate ()
  1145. {
  1146. try
  1147. {
  1148. //检查是否存在文件夹
  1149. //string subPath = @"C:\MetisTemp";
  1150. string subPath = System.Configuration.ConfigurationManager.AppSettings["TempPath"];
  1151. if (false == System.IO.Directory.Exists(subPath))
  1152. {
  1153. //创建pic文件夹
  1154. System.IO.Directory.CreateDirectory(subPath);
  1155. }
  1156. else
  1157. {
  1158. DirectoryInfo di = new DirectoryInfo(subPath);
  1159. FileSystemInfo[] fileinfo = di.GetFileSystemInfos();
  1160. foreach (FileSystemInfo item in fileinfo)
  1161. {
  1162. item.Delete();
  1163. // File.Delete(item.FullName);
  1164. }
  1165. }
  1166. string savepath = subPath + "\\" + name + ".png";
  1167. string isCpu = System.Configuration.ConfigurationManager.AppSettings["CpuORGpu"];
  1168. bitmap.Save(savepath, System.Drawing.Imaging.ImageFormat.Png);
  1169. //1金相/2析出物 0是cpu,1是GPU 尺寸0是自动算
  1170. string sArguments = subPath + " " + name + ".png 1 " + isCpu + " 0";
  1171. System.Diagnostics.Process p = new System.Diagnostics.Process();
  1172. //p.StartInfo.FileName = System.Environment.CurrentDirectory + "\\crystal\\crystal.exe";
  1173. p.StartInfo.FileName = System.Environment.CurrentDirectory + "\\educt\\educt.exe";
  1174. p.StartInfo.Arguments = sArguments;//python命令的参数
  1175. p.StartInfo.UseShellExecute = false;
  1176. p.StartInfo.RedirectStandardInput = true;
  1177. p.StartInfo.RedirectStandardOutput = true;
  1178. p.StartInfo.RedirectStandardError = true;
  1179. p.StartInfo.CreateNoWindow = true;
  1180. string strOutput = null;
  1181. p.Start();
  1182. strOutput = p.StandardOutput.ReadToEnd();
  1183. p.WaitForExit();
  1184. p.Close();
  1185. string newbitmap = subPath + "\\mask.jpg";
  1186. Mat mask = Cv2.ImRead(newbitmap);
  1187. newMat = this.PerformProcessGetdata(mask, out data);
  1188. if (bmc != null) { bmc.data = data; bmc.isedit = true; }
  1189. if (bc != null) { bc.data = data; bc.isedit = true; }
  1190. documentWorkspace.PhaseModels[0].mat = newMat;
  1191. documentWorkspace.PhaseModels[0].color = (bmc != null ? bmc.BinaryBackColor.ToArgb() : bc.BinaryBackColor.ToArgb());
  1192. documentWorkspace.Refresh();
  1193. }
  1194. catch (Exception e)
  1195. {
  1196. }
  1197. finally
  1198. {
  1199. progressEvents.EndOperation(OperationResult.Finished);
  1200. }
  1201. };
  1202. procClass.StartProgressAction(parentPrimary, itemCount, copyThreadProcCrystal, progressEvents, null);
  1203. }
  1204. }
  1205. #endregion
  1206. break;
  1207. }
  1208. }
  1209. /// <summary>
  1210. /// 同心圆绘制返回数据
  1211. /// </summary>
  1212. /// <returns></returns>
  1213. public List<List<int>> getCircleDate(int count)
  1214. {
  1215. if (bmc != null) { bmc.isedit = true; }
  1216. if (bc != null) { bc.isedit = true; }
  1217. CilCount = count;
  1218. List<List<int>> data = new List<List<int>>() { };
  1219. Bitmap bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
  1220. // Mat maptomat = getimage(bitmap);
  1221. if (LunkMat != null && LunkMat.Rows > 10)
  1222. {
  1223. }
  1224. else
  1225. {
  1226. Mat maptomat = getimage(bitmap);
  1227. LunkMat = maptomat.Clone();
  1228. }
  1229. List<Scalar> colorList = new List<Scalar>() { new Scalar(0, 0, 255, 255), new Scalar(0, 255, 0, 255), new Scalar(0, 255, 255, 255), new Scalar(128, 0, 128, 255), new Scalar(230, 216, 173, 255) };
  1230. double dist = 0;
  1231. double maxdist = 0;
  1232. if (SetCenter != null && SetCenter.X > 0)
  1233. {
  1234. center = SetCenter;
  1235. if (count > 0)
  1236. r = R / count;
  1237. else
  1238. r = R;
  1239. }
  1240. else
  1241. {
  1242. InputArray contoursAll = InputArray.Create(maxContour);
  1243. List<OpenCvSharp.Point> outArr = new List<OpenCvSharp.Point>();
  1244. OutputArray hull = OutputArray.Create(outArr);
  1245. Cv2.ConvexHull(contoursAll, hull, true);
  1246. for (int i = 0; i < LunkMat.Cols; i = i + 50)
  1247. {
  1248. for (int j = 0; j < LunkMat.Rows; j = j + 50)
  1249. {
  1250. OpenCvSharp.Point point = new OpenCvSharp.Point(i, j);
  1251. dist = Cv2.PointPolygonTest(outArr.ToArray(), point, true);
  1252. if (dist > maxdist)
  1253. {
  1254. maxdist = dist;
  1255. center = point;
  1256. }
  1257. }
  1258. }
  1259. R = Convert.ToInt32(maxdist);
  1260. if (count > 0)
  1261. r = Convert.ToInt32(maxdist) / count;
  1262. else
  1263. r = R;
  1264. }
  1265. action.Lists.Add(new Args() { Key = "CircleCount", Value = count });
  1266. action.Lists.Add(new Args() { Key = "CircleR", Value = r });
  1267. action.Lists.Add(new Args() { Key = "Center", Value = center });
  1268. action.Lists.Add(new Args() { Key = "SelPointFs", Value = -1 });
  1269. Mat newMat = this.PerformProcessGetdata(LunkMat, out data);
  1270. if (data.Count > 0)
  1271. {
  1272. List<int> CircleDate = data[0];
  1273. CircleDate[CircleDate.Count - 1] = Convert.ToInt32(maxArea);
  1274. }
  1275. documentWorkspace.PhaseModels[0].mat = newMat;
  1276. documentWorkspace.PhaseModels[0].color = (bmc != null ? bmc.BinaryBackColor.ToArgb() : bc.BinaryBackColor.ToArgb());
  1277. documentWorkspace.Refresh();
  1278. return data;
  1279. }
  1280. /// <summary>
  1281. /// 手动同心圆绘制返回数据
  1282. /// </summary>
  1283. /// <returns></returns>
  1284. public List<List<int>> getCircleDate(Dictionary<int, Color> ListRadiusColor)
  1285. {
  1286. if (bmc != null) { bmc.isedit = true; }
  1287. if (bc != null) { bc.isedit = true; }
  1288. List<List<int>> data = new List<List<int>>() { };
  1289. Bitmap bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
  1290. // Mat maptomat = getimage(bitmap);
  1291. if (LunkMat != null && LunkMat.Rows > 10)
  1292. {
  1293. }
  1294. else
  1295. {
  1296. Mat maptomat = getimage(bitmap);
  1297. LunkMat = maptomat.Clone();
  1298. }
  1299. action.Lists.Add(new Args() { Key = "ListRadiusColor", Value = ListRadiusColor });
  1300. action.Lists.Add(new Args() { Key = "Center", Value = center });
  1301. action.Lists.Add(new Args() { Key = "SelPointFs", Value = -1 });
  1302. Mat newMat = this.PerformProcessGetdata(LunkMat, out data);
  1303. if (data.Count > 0)
  1304. {
  1305. List<int> CircleDate = data[0];
  1306. CircleDate[CircleDate.Count - 1] = Convert.ToInt32(maxArea);
  1307. }
  1308. documentWorkspace.PhaseModels[0].mat = newMat;
  1309. documentWorkspace.PhaseModels[0].color = (bmc != null ? bmc.BinaryBackColor.ToArgb() : bc.BinaryBackColor.ToArgb());
  1310. documentWorkspace.Refresh();
  1311. return data;
  1312. }
  1313. /// <summary>
  1314. /// 绘制轮廓
  1315. /// </summary>
  1316. /// <returns></returns>
  1317. public List<List<int>> DrwLunKuo(List<List<PointF>> pointFs, List<List<PointF>> KongPointFs, List<PointF> delPointFs)
  1318. {
  1319. if (this.listView1.Items.Count == 0)
  1320. {
  1321. return null;
  1322. }
  1323. lineList = pointFs;
  1324. kongLineList = KongPointFs;
  1325. delLineList = delPointFs;
  1326. List<List<int>> data = new List<List<int>>() { };
  1327. Bitmap bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
  1328. Mat maptomat = getimage(bitmap);
  1329. // Mat maptomat = getLineMat(bitmap);
  1330. LunkMat = maptomat.Clone();
  1331. action.Lists.Add(new Args() { Key = "SelPointFs", Value = -1 });
  1332. action.Lists.Add(new Args() { Key = "DelPointFs", Value = delPointFs });
  1333. Mat newMat = this.PerformProcessGetdata(maptomat, out data);
  1334. documentWorkspace.PhaseModels[0].mat = newMat;
  1335. documentWorkspace.PhaseModels[0].color = (bmc != null ? bmc.BinaryBackColor.ToArgb() : bc.BinaryBackColor.ToArgb());
  1336. documentWorkspace.Refresh();
  1337. List<int> CircleDate = data[0];
  1338. CircleDate[CircleDate.Count - 1] = Convert.ToInt32(maxArea);
  1339. return data;
  1340. }
  1341. /// <summary>
  1342. /// 重新绘制轮廓
  1343. /// </summary>
  1344. /// <returns></returns>
  1345. public List<List<int>> DrwLunKuoNew(List<List<PointF>> pointFs, List<List<PointF>> KongPointFs, List<PointF> delPointFs)
  1346. {
  1347. lineList = pointFs;
  1348. kongLineList = KongPointFs;
  1349. delLineList = delPointFs;
  1350. List<List<int>> data = new List<List<int>>() { };
  1351. Bitmap bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
  1352. Mat maptomat = getLineMat(bitmap);
  1353. // Mat maptomat = getLineMat(bitmap);
  1354. LunkMat = maptomat.Clone();
  1355. action.Lists.Add(new Args() { Key = "SelPointFs", Value = -1 });
  1356. action.Lists.Add(new Args() { Key = "DelPointFs", Value = delPointFs });
  1357. Mat newMat = this.PerformProcessGetdata(maptomat, out data);
  1358. documentWorkspace.PhaseModels[0].mat = newMat;
  1359. documentWorkspace.PhaseModels[0].color = (bmc != null ? bmc.BinaryBackColor.ToArgb() : bc.BinaryBackColor.ToArgb());
  1360. documentWorkspace.Refresh();
  1361. List<int> CircleDate = data[0];
  1362. CircleDate[CircleDate.Count - 1] = Convert.ToInt32(maxArea);
  1363. return data;
  1364. }
  1365. /// <summary>
  1366. /// 选择颗粒
  1367. /// </summary>
  1368. /// <returns></returns>
  1369. public void DrwLunKuoSel(int index)
  1370. {
  1371. List<List<int>> data = new List<List<int>>() { };
  1372. action.Lists.Add(new Args() { Key = "SelPointFs", Value = index });
  1373. Mat newMat = this.PerformProcessGetdata(LunkMat, out data);
  1374. documentWorkspace.PhaseModels[0].mat = newMat;
  1375. documentWorkspace.PhaseModels[0].color = (bmc != null ? bmc.BinaryBackColor.ToArgb() : bc.BinaryBackColor.ToArgb());
  1376. documentWorkspace.Refresh();
  1377. }
  1378. /// <summary>
  1379. /// 选择隔膜孔隙
  1380. /// </summary>
  1381. /// <returns></returns>
  1382. public void MembranesSel(int index)
  1383. {
  1384. List<List<int>> data = new List<List<int>>() { };
  1385. Bitmap bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
  1386. action.Lists.Add(new Args() { Key = "SelPointFs", Value = index });
  1387. Mat newMat = this.PerformProcessGetdata(OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap), out data);
  1388. documentWorkspace.PhaseModels[0].mat = newMat;
  1389. documentWorkspace.Refresh();
  1390. }
  1391. /// <summary>
  1392. /// 绘制轮廓单晶
  1393. /// </summary>
  1394. /// <returns></returns>
  1395. public List<List<int>> DrwLunKuoDJ(List<List<PointF>> pointFs, List<List<PointF>> KongPointFs, List<PointF> delPointFs)
  1396. {
  1397. lineList = pointFs;
  1398. kongLineList = KongPointFs;
  1399. delLineList = delPointFs;
  1400. List<List<int>> data = new List<List<int>>() { };
  1401. Bitmap bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
  1402. action.Lists.Add(new Args() { Key = "DelPointFs", Value = delPointFs });
  1403. Mat newMat = this.PerformProcessGetdata(OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap), out data);
  1404. documentWorkspace.PhaseModels[0].mat = newMat;
  1405. documentWorkspace.PhaseModels[0].color = (bmc != null ? bmc.BinaryBackColor.ToArgb() : bc.BinaryBackColor.ToArgb());
  1406. documentWorkspace.Refresh();
  1407. return data;
  1408. }
  1409. /// <summary>
  1410. /// 绘制轮廓二次球均匀性
  1411. /// </summary>
  1412. /// <returns></returns>
  1413. public List<List<int>> DrwLunKuoBallAndCrystal(List<int> options, List<PointF> KongPointFs, List<PointF> delPointFs, List<List<PointF>> LKPointFs)
  1414. {
  1415. kailie_ball = KongPointFs;
  1416. delLineList = delPointFs;
  1417. List<List<int>> data = new List<List<int>>() { };
  1418. ProgressThreadProcClass procClass = new ProgressThreadProcClass();
  1419. int itemCount = 100;
  1420. Mat newMat = new Mat();
  1421. Bitmap bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
  1422. ProgressThreadProcClass.IFileTransferProgressEvents progressEvents = new ProgressThreadProcClass.IFileTransferProgressEvents();
  1423. System.Threading.ThreadStart copyThreadProc =
  1424. delegate ()
  1425. {
  1426. try
  1427. {
  1428. action.Lists.Add(new Args() { Key = "BlurSiaze", Value = options[0] });
  1429. action.Lists.Add(new Args() { Key = "param2", Value = options[1] });
  1430. action.Lists.Add(new Args() { Key = "minRadius", Value = options[2] });
  1431. action.Lists.Add(new Args() { Key = "maxRadius", Value = options[3] });
  1432. action.Lists.Add(new Args() { Key = "boundary", Value = options[4] });
  1433. action.Lists.Add(new Args() { Key = "BallPointFs", Value = kailie_ball });
  1434. action.Lists.Add(new Args() { Key = "CrystalPointFs", Value = delLineList });
  1435. action.Lists.Add(new Args() { Key = "CrystalLunkuo", Value = LKPointFs });
  1436. newMat = this.PerformProcessGetdata(OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap), out data);
  1437. }
  1438. catch (Exception e)
  1439. {
  1440. }
  1441. finally
  1442. {
  1443. progressEvents.EndOperation(OperationResult.Finished);
  1444. }
  1445. };
  1446. procClass.StartProgressAction(/*currentForm*/parentCrystal, itemCount, copyThreadProc, progressEvents, null);
  1447. if (bmc != null) { bmc.data = data; bmc.isedit = true; }
  1448. if (bc != null) { bc.data = data; bc.isedit = true; }
  1449. documentWorkspace.PhaseModels[0].mat = newMat;
  1450. documentWorkspace.PhaseModels[0].color = (bmc != null ? bmc.BinaryBackColor.ToArgb() : bc.BinaryBackColor.ToArgb());
  1451. documentWorkspace.Refresh();
  1452. return data;
  1453. }
  1454. /// <summary>
  1455. /// 初始化二值化相关的变量
  1456. /// </summary>
  1457. public void initParams()
  1458. {
  1459. string xmlFilePath = Application.StartupPath + "\\Config\\" + Startup.instance.SettingPrefix + "\\BinaryConfig\\Default_" + this.menuId + ".xml";
  1460. bool createNewFile = !System.IO.File.Exists(xmlFilePath);
  1461. if (createNewFile)
  1462. xmlFilePath = Application.StartupPath + "\\Config\\" + Startup.instance.SettingPrefix + "\\BinaryExtraction\\Default.xml";
  1463. this.binaryExtractionModel = XmlSerializeHelper.DESerializer<BinaryExtractionModel>(FileOperationHelper.ReadStringFromFile(xmlFilePath, FileMode.Open));
  1464. if (createNewFile)
  1465. this.binaryExtractionModel.BinaryCheckFlag = 0;
  1466. if (imageType == 2)
  1467. {
  1468. //binaryExtractionModel.ColorOneEnd = 200;
  1469. pointsize = Convert.ToDouble(binaryExtractionModel.ColorOneStart) / 100;
  1470. border = binaryExtractionModel.ColorOneEnd / 100;
  1471. HW = Convert.ToDouble(binaryExtractionModel.ColorTwoStart) / 100;
  1472. AreaRatio = Convert.ToDouble(binaryExtractionModel.ColorTwoEnd) / 100;
  1473. CheckState = binaryExtractionModel.ColorThreeStart;
  1474. borderBottom = binaryExtractionModel.ColorThreeEnd / 100;
  1475. numDecimals = Convert.ToInt32(binaryExtractionModel.DebrisAreaStart);
  1476. }
  1477. if (imageType == 4)
  1478. {
  1479. binaryExtractionModel.ColorOneEnd = 200;
  1480. }
  1481. this.initParamsToAction();
  1482. }
  1483. /// <summary>
  1484. /// 把参数的值设置到action
  1485. /// </summary>
  1486. public void initParamsToAction()
  1487. {
  1488. foreach (Args args in action.Lists)
  1489. {
  1490. if (args.Key == "colorInterval")
  1491. args.Value = this.binaryExtractionModel.ColorInterval;
  1492. else if (args.Key == "binaryStyle")
  1493. args.Value = this.binaryExtractionModel.BinaryStyle;
  1494. else if (args.Key == "scope1")
  1495. {
  1496. ((List<double>)args.Value)[0] = (int)(this.binaryExtractionModel.ColorOneStart);
  1497. ((List<double>)args.Value)[1] = (int)(this.binaryExtractionModel.ColorOneEnd);
  1498. }
  1499. else if (args.Key == "scope2")
  1500. {
  1501. ((List<double>)args.Value)[0] = (int)(this.binaryExtractionModel.ColorTwoStart);
  1502. ((List<double>)args.Value)[1] = (int)(this.binaryExtractionModel.ColorTwoEnd);
  1503. }
  1504. else if (args.Key == "scope3")
  1505. {
  1506. ((List<double>)args.Value)[0] = (int)(this.binaryExtractionModel.ColorThreeStart);
  1507. ((List<double>)args.Value)[1] = (int)(this.binaryExtractionModel.ColorThreeEnd);
  1508. }
  1509. else if (args.Key == "phaseColor")//#22092
  1510. {
  1511. args.Value = this.binaryExtractionModel.PhaseColor;
  1512. }
  1513. }
  1514. }
  1515. /// <summary>
  1516. /// 保存变量
  1517. /// </summary>
  1518. public void saveParams(List<int> paramsList)
  1519. {
  1520. this.binaryExtractionModel.ColorOneStart = paramsList[0];
  1521. this.binaryExtractionModel.ColorOneEnd = paramsList[1];
  1522. this.binaryExtractionModel.ColorTwoStart = paramsList[2];
  1523. this.binaryExtractionModel.ColorTwoEnd = paramsList[3];
  1524. this.binaryExtractionModel.ColorThreeEnd = paramsList[4];
  1525. this.binaryExtractionModel.ColorThreeStart = paramsList[6];
  1526. this.binaryExtractionModel.DebrisAreaStart = paramsList[5];
  1527. string xmlFilePath = Application.StartupPath + "\\Config\\" + Startup.instance.SettingPrefix + "\\BinaryConfig\\Default_" + this.menuId + ".xml";
  1528. string userInfoXml = XmlSerializeHelper.XmlSerialize<BinaryExtractionModel>(this.binaryExtractionModel);
  1529. FileOperationHelper.WriteStringToFile(userInfoXml, xmlFilePath, System.IO.FileMode.Create);
  1530. }
  1531. /// <summary>
  1532. /// 保存二值化相关的变量
  1533. /// </summary>
  1534. public void saveParams()
  1535. {
  1536. string xmlFilePath = Application.StartupPath + "\\Config\\" + Startup.instance.SettingPrefix + "\\BinaryConfig\\Default_" + this.menuId + ".xml";
  1537. string userInfoXml = XmlSerializeHelper.XmlSerialize<BinaryExtractionModel>(this.binaryExtractionModel);
  1538. FileOperationHelper.WriteStringToFile(userInfoXml, xmlFilePath, System.IO.FileMode.Create);
  1539. }
  1540. #region 内部类
  1541. internal class LocalListViewItem
  1542. {
  1543. public DocumentWorkspace Value { get; }
  1544. public string Display { get; }
  1545. public LocalListViewItem(DocumentWorkspace Value, string Display)
  1546. {
  1547. this.Value = Value;
  1548. this.Display = Display;
  1549. }
  1550. }
  1551. internal class DocumentItem
  1552. {
  1553. public Bitmap bitmap;
  1554. public GraphicsList graphicsList;
  1555. public List<PhaseModel> phaseModels;
  1556. public DocumentItem(Bitmap bitmap, GraphicsList graphicsList, List<PhaseModel> phaseModels)
  1557. {
  1558. this.bitmap = bitmap;
  1559. this.graphicsList = graphicsList;
  1560. this.phaseModels = phaseModels;
  1561. }
  1562. }
  1563. #endregion
  1564. #region 前驱截面
  1565. private Mat getLineMat(Bitmap img)
  1566. {
  1567. Mat mat = OpenCvSharp.Extensions.BitmapConverter.ToMat(img);
  1568. double dist = 0;
  1569. double maxdist = 0;
  1570. List<PointF> pointList = lineList[0];
  1571. List<List<OpenCvSharp.Point>> list = new List<List<OpenCvSharp.Point>>();
  1572. List<OpenCvSharp.Point> point = new List<OpenCvSharp.Point>();
  1573. if (kongLineList.Count > 0)
  1574. {
  1575. List<List<OpenCvSharp.Point>> Allkonglist = new List<List<OpenCvSharp.Point>>() { };
  1576. for (int i = 0; i < kongLineList.Count; i++)
  1577. {
  1578. List<OpenCvSharp.Point> konglist = new List<OpenCvSharp.Point>();
  1579. for (int j = 0; j < kongLineList[i].Count; j++)
  1580. {
  1581. OpenCvSharp.Point po = new OpenCvSharp.Point() { X = (int)kongLineList[i][j].X, Y = (int)kongLineList[i][j].Y };
  1582. konglist.Add(po);
  1583. }
  1584. Allkonglist.Add(konglist);
  1585. }
  1586. for (int kong = 0; kong < kongLineList.Count; kong++)
  1587. {
  1588. Cv2.DrawContours(mat, Allkonglist, kong, new Scalar(0, 0, 0, 255), Cv2.FILLED);
  1589. }
  1590. }
  1591. for (int i = 0; i < pointList.Count(); i++)
  1592. {
  1593. point.Add(new OpenCvSharp.Point() { X = (int)pointList[i].X, Y = (int)pointList[i].Y });
  1594. }
  1595. list.Add(point);
  1596. Mat mask = Mat.Zeros(mat.Size(), MatType.CV_8UC1);
  1597. Cv2.DrawContours(mask, list, 0, new Scalar(255, 255, 255, 255), -1);
  1598. maxContour = point.ToArray();
  1599. InputArray contoursAll = InputArray.Create(maxContour);
  1600. List<OpenCvSharp.Point> outArr = new List<OpenCvSharp.Point>();
  1601. OutputArray hull = OutputArray.Create(outArr);
  1602. maxArea = Cv2.ContourArea(maxContour);
  1603. Cv2.ConvexHull(contoursAll, hull, true);
  1604. if (SetCenter != null && SetCenter.X > 0&& CilCount>0)
  1605. {
  1606. center = SetCenter;
  1607. r = R / CilCount;
  1608. }
  1609. else
  1610. {
  1611. for (int i = 0; i < mat.Cols; i = i + 50)
  1612. {
  1613. for (int j = 0; j < mat.Rows; j = j + 50)
  1614. {
  1615. OpenCvSharp.Point point1 = new OpenCvSharp.Point(i, j);
  1616. dist = Cv2.PointPolygonTest(outArr, point1, true);
  1617. if (dist > maxdist)
  1618. {
  1619. maxdist = dist;
  1620. center = point1;
  1621. }
  1622. }
  1623. }
  1624. R = Convert.ToInt32(maxdist);
  1625. r = Convert.ToInt32(maxdist);
  1626. }
  1627. // r = r - 10;
  1628. action.Lists.Add(new Args() { Key = "maxContour", Value = maxContour });
  1629. action.Lists.Add(new Args() { Key = "CircleCount", Value = CilCount });
  1630. action.Lists.Add(new Args() { Key = "CircleR", Value = r });
  1631. action.Lists.Add(new Args() { Key = "Center", Value = center });
  1632. action.Lists.Add(new Args() { Key = "imageType", Value = 1 });
  1633. action.Lists.Add(new Args() { Key = "SelPointFs", Value = -1 });
  1634. Mat dst = new Mat();
  1635. mat.CopyTo(dst, mask);
  1636. return dst;
  1637. }
  1638. private Mat getimage(Bitmap img)
  1639. {
  1640. Mat mat = OpenCvSharp.Extensions.BitmapConverter.ToMat(img);
  1641. Mat g_grayImage = new Mat();
  1642. Mat g_dstImage = new Mat();
  1643. Mat g_bwImage = new Mat();
  1644. Mat mask = Mat.Zeros(mat.Size(), MatType.CV_8UC1);
  1645. Mat dst = new Mat();
  1646. if (lineList.Count > 0)
  1647. {
  1648. for (int line = 0; line < lineList.Count; line++)
  1649. {
  1650. List<PointF> pointList = lineList[line];
  1651. for (int i = 0; i < pointList.Count - 1; i++)
  1652. {
  1653. Cv2.Line(mat, new OpenCvSharp.Point() { X = (int)pointList[i].X, Y = (int)pointList[i].Y }, new OpenCvSharp.Point() { X = (int)pointList[i + 1].X, Y = (int)pointList[i + 1].Y }, new Scalar(0, 0, 0), 20);
  1654. }
  1655. }
  1656. }
  1657. if (kongLineList.Count > 0)
  1658. {
  1659. List<List<OpenCvSharp.Point>> Allkonglist = new List<List<OpenCvSharp.Point>>() { };
  1660. for (int i = 0; i < kongLineList.Count; i++)
  1661. {
  1662. List<OpenCvSharp.Point> konglist = new List<OpenCvSharp.Point>();
  1663. for (int j = 0; j < kongLineList[i].Count; j++)
  1664. {
  1665. OpenCvSharp.Point point = new OpenCvSharp.Point() { X = (int)kongLineList[i][j].X, Y = (int)kongLineList[i][j].Y };
  1666. konglist.Add(point);
  1667. }
  1668. Allkonglist.Add(konglist);
  1669. }
  1670. for (int kong = 0; kong < kongLineList.Count; kong++)
  1671. {
  1672. Cv2.DrawContours(mat, Allkonglist, kong, new Scalar(0, 0, 0, 255), Cv2.FILLED);
  1673. }
  1674. }
  1675. //灰度图
  1676. Cv2.CvtColor(mat, g_grayImage, ColorConversionCodes.BGR2GRAY);
  1677. Cv2.Erode(g_grayImage, g_grayImage, null);
  1678. Cv2.Erode(g_grayImage, g_grayImage, null);
  1679. //算子
  1680. InputArray kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(5, 5), new OpenCvSharp.Point(2, 2));
  1681. //闭操作
  1682. Cv2.MorphologyEx(g_grayImage, g_dstImage, MorphTypes.Close, kernel, new OpenCvSharp.Point(-1, -1));
  1683. //平均阈值
  1684. Scalar scalar = Cv2.Mean(g_dstImage);
  1685. double val = scalar.Val0 + 11;
  1686. //图像二值化
  1687. Cv2.Threshold(g_dstImage, g_bwImage, val, 255, ThresholdTypes.Binary);
  1688. OpenCvSharp.Point[][] contours = new OpenCvSharp.Point[][] { };
  1689. HierarchyIndex[] hierarchyIndex = new HierarchyIndex[] { };
  1690. //轮廓
  1691. Cv2.FindContours(g_bwImage, out contours, out hierarchyIndex, RetrievalModes.External, ContourApproximationModes.ApproxNone);
  1692. Mat view = mask.Clone();
  1693. int maxcontourIdx = 0;
  1694. maxArea = 0;
  1695. for (int i = 0; i < contours.Length; i++)
  1696. {
  1697. double area = Cv2.ContourArea(contours[i]);
  1698. if (area > maxArea)
  1699. {
  1700. maxArea = area;
  1701. maxContour = contours[i];
  1702. maxcontourIdx = i;
  1703. }
  1704. //Cv2.DrawContours(view, contours, i, new Scalar(255, 255, 255, 255), -1);
  1705. }
  1706. //Mat matret = new Mat(mat.Rows, mat.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 0));
  1707. //Cv2.DrawContours(matret, contours, maxcontourIdx, new Scalar(255, 0, 255, 255), 2);
  1708. InputArray contoursAll = InputArray.Create(contours[maxcontourIdx]);
  1709. List<OpenCvSharp.Point> outArr = new List<OpenCvSharp.Point>();
  1710. List<OpenCvSharp.Point> hullpoint = new List<OpenCvSharp.Point>();
  1711. OutputArray hull = OutputArray.Create(outArr);
  1712. Cv2.ConvexHull(contoursAll, hull, true);
  1713. Cv2.DrawContours(mask, new List<List<OpenCvSharp.Point>> { outArr }, 0, new Scalar(255, 255, 255, 255), -1);
  1714. action.Lists.Add(new Args() { Key = "maxContour", Value = outArr.ToArray() });
  1715. maxContour = outArr.ToArray();
  1716. //using (new Window("ss",WindowMode.Normal, view))
  1717. //{
  1718. // Cv2.WaitKey(0);
  1719. //}
  1720. maxArea = Cv2.ContourArea(outArr);
  1721. mat.CopyTo(dst, mask);
  1722. //List<OpenCvSharp.Point> ret = expand_polygon(maxContour);
  1723. //Cv2.DrawContours(dst, new List<List<OpenCvSharp.Point>> { ret }, 0, new Scalar(255, 255, 255, 255), -1);
  1724. //Cv2.ImShow("ss", dst);
  1725. return dst;
  1726. }
  1727. private List<OpenCvSharp.Point> expand_polygon(OpenCvSharp.Point[] pList)
  1728. {
  1729. List<OpenCvSharp.Point> points = new List<OpenCvSharp.Point>() { };
  1730. List<Point2f> dpList = new List<Point2f>() { }, ndpList = new List<Point2f>() { };
  1731. int count = pList.Count();
  1732. for (int i = 0; i < count; i++)
  1733. {
  1734. int next = (i == (count - 1) ? 0 : (i + 1));
  1735. dpList.Add(pList[next] - pList[i]);
  1736. double unitLen = 1.0 / Math.Sqrt(dpList[i].DotProduct(dpList[i]));
  1737. ndpList.Add(dpList[i] * unitLen);
  1738. }
  1739. // 3. compute Line
  1740. float SAFELINE = -1.3f;//负数为内缩, 正数为外扩。 需要注意算法本身并没有检测内缩多少后折线会自相交,那不是本代码的示范意图
  1741. for (int i = 0; i < count; i++)
  1742. {
  1743. int startIndex = (i == 0 ? (count - 1) : (i - 1));
  1744. int endIndex = i;
  1745. float sinTheta = (float)ndpList[startIndex].CrossProduct(ndpList[endIndex]);
  1746. Point2f orientVector = ndpList[endIndex] - ndpList[startIndex];//i.e. PV2-V1P=PV2+PV1
  1747. OpenCvSharp.Point temp_out;
  1748. temp_out.X = Convert.ToInt32(pList[i].X + SAFELINE / sinTheta * orientVector.X);
  1749. temp_out.Y = Convert.ToInt32(pList[i].Y + SAFELINE / sinTheta * orientVector.Y);
  1750. points.Add(temp_out);
  1751. }
  1752. return points;
  1753. }
  1754. /// <summary>
  1755. /// 自动阈值
  1756. /// </summary>
  1757. /// <param name="sender"></param>
  1758. /// <param name="e"></param>
  1759. public void bcDefault()
  1760. {
  1761. if (bc == null && bmc == null)
  1762. return;
  1763. Bitmap bitmap = null;
  1764. if (listView1.FocusedItem != null || this.listView1.SelectedItems != null && this.listView1.SelectedItems.Count > 0)
  1765. bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
  1766. if (bitmap != null)
  1767. {
  1768. //先计算阈值
  1769. Mat mat = OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap);
  1770. Mat gray = mat.CvtColor(ColorConversionCodes.BGR2GRAY);
  1771. double otsu = Cv2.Threshold(gray, gray, 0, 255, ThresholdTypes.Triangle/*.Otsu*/);
  1772. if (otsu <= 10 || otsu >= 245)
  1773. {
  1774. otsu = Cv2.Threshold(mat.CvtColor(ColorConversionCodes.BGR2GRAY), gray, 0, 255, ThresholdTypes.Otsu);//.Triangle
  1775. }
  1776. //如果当前是两个区间,则需要重新计算一次
  1777. if (this.ColorInterval == 2)
  1778. {
  1779. if (bmc != null)
  1780. bmc.OnInverseClickAction();
  1781. else
  1782. bc.OnInverseClickAction();
  1783. this.ColorInterval = (bmc != null ? bmc.getInverseStyle() : bc.getInverseStyle());
  1784. }
  1785. else
  1786. {
  1787. if (bmc != null)
  1788. bmc.setInverseStyle(1);
  1789. else
  1790. bc.setInverseStyle(1);
  1791. }
  1792. // Scalar scalar = Cv2.Mean(mat);
  1793. int val = 0;
  1794. switch (imageType)
  1795. {
  1796. case 2:
  1797. val = GetDefultValueForCrystal(mat);
  1798. //给控件赋值
  1799. if (bmc != null)
  1800. bmc.scope1Start = val;
  1801. else
  1802. bc.scope1Start = val;
  1803. if (bmc != null)
  1804. bmc.scope1End = 200;
  1805. else
  1806. bc.scope1End = 200;
  1807. break;
  1808. case 3:
  1809. val = GetDefultValueForCrystal(mat);
  1810. //给控件赋值
  1811. if (bmc != null)
  1812. bmc.scope1Start = val;
  1813. else
  1814. bc.scope1Start = val;
  1815. if (bmc != null)
  1816. bmc.scope1End = 245;
  1817. else
  1818. bc.scope1End = 245;
  1819. break;
  1820. case 4:
  1821. val = GetDefultValueForBall(mat);
  1822. //给控件赋值
  1823. if ((bmc != null && bmc.scope1Start == val) || (bc != null && bc.scope1Start == val))
  1824. {
  1825. val = val + 1;
  1826. }
  1827. if (bmc != null)
  1828. bmc.scope1Start = val;
  1829. else
  1830. bc.scope1Start = val;
  1831. if (bmc != null)
  1832. bmc.scope1End = 200;
  1833. else
  1834. bc.scope1End = 200;
  1835. break;
  1836. case 1:
  1837. val = GetDefultValue(mat);
  1838. //给控件赋值
  1839. if (bmc != null)
  1840. bmc.scope1Start = 0;
  1841. else
  1842. bc.scope1Start = 0;
  1843. if (bmc != null)
  1844. bmc.scope1End = val;
  1845. else
  1846. bc.scope1End = val;
  1847. break;
  1848. case 5:
  1849. val = GetDefultValue(mat);
  1850. //给控件赋值
  1851. if (bmc != null)
  1852. bmc.scope1Start = 0;
  1853. else
  1854. bc.scope1Start = 0;
  1855. if (bmc != null)
  1856. bmc.scope1End = val;
  1857. else
  1858. bc.scope1End = val;
  1859. break;
  1860. }
  1861. //处理直方图
  1862. if (bmc != null)
  1863. bmc.UpdateVerticalBarWithOneScope(Convert.ToInt32(bmc.scope1Start), Convert.ToInt32(bmc.scope1End));
  1864. else
  1865. bc.UpdateVerticalBarWithOneScope(Convert.ToInt32(bmc.scope1Start), Convert.ToInt32(bc.scope1End));
  1866. mat.Dispose();
  1867. GC.Collect();
  1868. }
  1869. else
  1870. {
  1871. MessageBox.Show(PdnResources.GetString("Menu.Pleaseselectapicturefirst.text"));
  1872. }
  1873. }
  1874. /// <summary>
  1875. /// 计算截面孔隙初始值
  1876. /// </summary>
  1877. /// <param name="mat"></param>
  1878. private int GetDefultValue(Mat mat)
  1879. {
  1880. //配置输出的结果存储的 空间 ,用MatND类型来存储结果
  1881. Mat hist = new Mat();
  1882. Mat Gaos = new Mat();
  1883. Cv2.GaussianBlur(mat, Gaos, new OpenCvSharp.Size(7, 7), 0);
  1884. //设置计算直方图的维度
  1885. int dims = 1;
  1886. //直方图的每一个维度的柱条的数目(就是将数值分组,共有多少组)
  1887. int[] histSize = { 255 };
  1888. Rangef[] pranges = new Rangef[1];//一个通道,范围
  1889. pranges[0].Start = 0.0F;//从0开始(含)
  1890. pranges[0].End = 256.0F;//到256结束(不含)
  1891. //6--计算直方图
  1892. Cv2.CalcHist(new Mat[1] { mat }, new int[] { 0 }, new Mat(), hist, dims, histSize, pranges);
  1893. int nHistSize = 256;
  1894. float maxY = 0;
  1895. int maxX = 0;
  1896. List<float> vs = new List<float>() { };
  1897. List<double> list = new List<double>() { };
  1898. for (int i = 1; i < nHistSize - 1; i++)
  1899. {
  1900. float y = hist.At<float>(i);
  1901. list.Add(y);
  1902. }
  1903. //maxX= GetHist(mat.Clone());
  1904. double[] dd = cubicSmooth7(list.ToArray(), list.Count());
  1905. int len = Convert.ToInt32(dd.Max()).ToString().Length;
  1906. int xline = 1;
  1907. for (int i = 0; i < len - 2; i++)
  1908. {
  1909. xline = xline * 10;
  1910. }
  1911. List<double> maxList = new List<double>() { };
  1912. for (int i = 3; i < list.Count() - 1; i++)
  1913. {
  1914. double Y2 = dd[i];
  1915. double Y1 = dd[i - 3];
  1916. double angleOfLine = Math.Atan2((Y2 - Y1), 3 * xline) * 180 / Math.PI;
  1917. maxList.Add(angleOfLine);
  1918. }
  1919. for (int i = maxList.Count() - 5; i > 10; i--)
  1920. {
  1921. double t1 = maxList[i];
  1922. double t2 = maxList[i + 1];
  1923. if (t1 - t2 < 0)
  1924. {
  1925. maxX = i;
  1926. break;
  1927. }
  1928. }
  1929. maxX = getMax(maxList, maxList.Count() - 15);
  1930. for (int i = maxX - 10; i > 10; i--)
  1931. {
  1932. double def = 0;
  1933. for (int j = i; j < i + 5; j++)
  1934. {
  1935. def = def + (dd[j + 1] - dd[j]);
  1936. }
  1937. }
  1938. //通过斜率计算坡底
  1939. List<double> angle = new List<double>() { };
  1940. for (int i = maxX - 10; i > 10; i--)
  1941. {
  1942. double Y2 = dd[i];
  1943. double Y1 = dd[i - 3];
  1944. double angleOfLine = Math.Atan2((Y2 - Y1), 3 * xline) * 180 / Math.PI;
  1945. angle.Add(angleOfLine);
  1946. }
  1947. int N = 0;
  1948. for (int i = 10; i < angle.Count() - 1; i++)
  1949. {
  1950. double t1 = angle[i];
  1951. double t2 = angle[i + 1];
  1952. if (t1 < 10 && t1 - t2 < 0.1)
  1953. {
  1954. N = i;
  1955. break;
  1956. }
  1957. }
  1958. //原点
  1959. PointF p0 = new PointF(0, 0);
  1960. //波峰顶点
  1961. PointF p1 = new PointF(maxX, Convert.ToInt32(dd[maxX]));
  1962. int pn = 0;
  1963. double maxD = 0;
  1964. //通过最远距离计算坡底
  1965. for (int i = maxX / 2; i < maxX; i++)
  1966. {
  1967. PointF p = new PointF(i, Convert.ToInt32(dd[i]));
  1968. double d = GetMinDistance(p0, p1, p);
  1969. if (maxD < d)
  1970. {
  1971. maxD = d;
  1972. pn = i;
  1973. }
  1974. }
  1975. return pn;
  1976. }
  1977. /// <summary>
  1978. /// 计算隔膜孔隙初始值
  1979. /// </summary>
  1980. /// <param name="mat"></param>
  1981. private int GetDefultValueForMem(Mat mat)
  1982. {
  1983. //配置输出的结果存储的 空间 ,用MatND类型来存储结果
  1984. Mat hist = new Mat();
  1985. Mat Gaos = new Mat();
  1986. Cv2.GaussianBlur(mat, Gaos, new OpenCvSharp.Size(7, 7), 0);
  1987. //设置计算直方图的维度
  1988. int dims = 1;
  1989. //直方图的每一个维度的柱条的数目(就是将数值分组,共有多少组)
  1990. int[] histSize = { 255 };
  1991. Rangef[] pranges = new Rangef[1];//一个通道,范围
  1992. pranges[0].Start = 0.0F;//从0开始(含)
  1993. pranges[0].End = 256.0F;//到256结束(不含)
  1994. //6--计算直方图
  1995. Cv2.CalcHist(new Mat[1] { mat }, new int[] { 0 }, new Mat(), hist, dims, histSize, pranges);
  1996. int nHistSize = 256;
  1997. float maxY = 0;
  1998. int maxX = 0;
  1999. List<float> vs = new List<float>() { };
  2000. List<double> list = new List<double>() { };
  2001. for (int i = 1; i < nHistSize - 1; i++)
  2002. {
  2003. float y = hist.At<float>(i);
  2004. list.Add(y);
  2005. if (y > maxY)
  2006. {
  2007. maxY = y;
  2008. maxX = i;
  2009. }
  2010. }
  2011. return maxX;
  2012. }
  2013. private int getMax(List<double> maxList, int init)
  2014. {
  2015. int ret = init;
  2016. for (int i = init; i > 10; i--)
  2017. {
  2018. int pre = 0;
  2019. int after = 0;
  2020. for (int t = i; t < i + 10; t++)
  2021. {
  2022. if (maxList[t] < 0)
  2023. {
  2024. pre++;
  2025. }
  2026. }
  2027. for (int t = i; t > i - 10; t--)
  2028. {
  2029. if (maxList[t] > 0)
  2030. {
  2031. after++;
  2032. }
  2033. }
  2034. if (pre > 8 && after > 8)
  2035. {
  2036. ret = i;
  2037. break;
  2038. }
  2039. //double t1 = maxList[i];
  2040. //double t2 = maxList[i + 1];
  2041. //if (t1>=10&&t2>=10&&t1-t2>0)
  2042. //{
  2043. // ret = i;
  2044. // break;
  2045. //}
  2046. }
  2047. return ret;
  2048. }
  2049. /// <summary>
  2050. /// 计算单晶初始值
  2051. /// </summary>
  2052. /// <param name="mat"></param>
  2053. private int GetDefultValueForCrystal(Mat mat)
  2054. {
  2055. //配置输出的结果存储的 空间 ,用MatND类型来存储结果
  2056. Mat hist = new Mat();
  2057. Mat Gaos = new Mat();
  2058. //Cv2.GaussianBlur(mat, Gaos, new OpenCvSharp.Size(7, 7), 0);
  2059. //设置计算直方图的维度
  2060. int dims = 1;
  2061. //直方图的每一个维度的柱条的数目(就是将数值分组,共有多少组)
  2062. int[] histSize = { 255 };
  2063. Rangef[] pranges = new Rangef[1];//一个通道,范围
  2064. pranges[0].Start = 0.0F;//从0开始(含)
  2065. pranges[0].End = 256.0F;//到256结束(不含)
  2066. //6--计算直方图
  2067. Cv2.CalcHist(new Mat[1] { mat }, new int[] { 0 }, new Mat(), hist, dims, histSize, pranges);
  2068. int nHistSize = 256;
  2069. float maxY = 0;
  2070. int maxX = 0;
  2071. List<float> vs = new List<float>() { };
  2072. List<double> list = new List<double>() { };
  2073. for (int i = 1; i < nHistSize - 1; i++)
  2074. {
  2075. float y = hist.At<float>(i);
  2076. list.Add(y);
  2077. }
  2078. //maxX= GetHist(mat.Clone());
  2079. double[] dd = cubicSmooth7(list.ToArray(), list.Count());
  2080. List<double> maxList = new List<double>() { };
  2081. for (int i = 3; i < list.Count() - 1; i++)
  2082. {
  2083. double Y2 = dd[i];
  2084. double Y1 = dd[i - 3];
  2085. double angleOfLine = Math.Atan2((Y2 - Y1), 30000) * 180 / Math.PI;
  2086. maxList.Add(angleOfLine);
  2087. }
  2088. for (int i = maxList.Count() - 5; i > 10; i--)
  2089. {
  2090. double t1 = maxList[i];
  2091. double t2 = maxList[i + 1];
  2092. if (t1 - t2 < 0)
  2093. {
  2094. maxX = i;
  2095. break;
  2096. }
  2097. }
  2098. int max2 = list.FindIndex(s => s == list.Max());
  2099. //波峰
  2100. maxX = getMax(maxList, maxList.Count() - 15);
  2101. //原点
  2102. PointF p0 = new PointF(255, 0);
  2103. //波峰顶点
  2104. PointF p1 = new PointF(max2, Convert.ToInt32(dd[max2]));
  2105. int pn = 0;
  2106. double maxD = 0;
  2107. if (imageType == 2)
  2108. {
  2109. //通过最远距离计算坡底
  2110. for (int i = max2; i < maxX; i++)
  2111. {
  2112. PointF p = new PointF(i, Convert.ToInt32(dd[i]));
  2113. double d = GetMinDistance(p0, p1, p);
  2114. if (maxD < d)
  2115. {
  2116. maxD = d;
  2117. pn = i;
  2118. }
  2119. }
  2120. return pn;
  2121. //return pn + (maxX - pn) / 2;
  2122. }
  2123. else
  2124. {
  2125. //通过最远距离计算坡底
  2126. for (int i = max2; i < 200; i++)
  2127. {
  2128. PointF p = new PointF(i, Convert.ToInt32(dd[i]));
  2129. double d = GetMinDistance(p0, p1, p);
  2130. if (maxD < d)
  2131. {
  2132. maxD = d;
  2133. pn = i;
  2134. }
  2135. }
  2136. return pn;
  2137. }
  2138. ////原点
  2139. //PointF p0 = new PointF(255, 0);
  2140. ////波峰顶点
  2141. //PointF p1 = new PointF(maxX, Convert.ToInt32(dd[maxX]));
  2142. //int pn = 0;
  2143. //double maxD = 0;
  2144. ////通过最远距离计算坡底
  2145. //for (int i = maxX; i < 245; i++)
  2146. //{
  2147. // PointF p = new PointF(i, Convert.ToInt32(dd[i]));
  2148. // double d = GetMinDistance(p0, p1, p);
  2149. // if (maxD < d)
  2150. // {
  2151. // maxD = d;
  2152. // pn = i;
  2153. // }
  2154. //}
  2155. //return pn;
  2156. // return maxX + N;
  2157. }
  2158. /// <summary>
  2159. /// 计算开裂球初始值
  2160. /// </summary>
  2161. /// <param name="mat"></param>
  2162. private int GetDefultValueForBall(Mat mat)
  2163. {
  2164. //配置输出的结果存储的 空间 ,用MatND类型来存储结果
  2165. Mat hist = new Mat();
  2166. int dims = 1;
  2167. //直方图的每一个维度的柱条的数目(就是将数值分组,共有多少组)
  2168. int[] histSize = { 255 };
  2169. Rangef[] pranges = new Rangef[1];//一个通道,范围
  2170. pranges[0].Start = 0.0F;//从0开始(含)
  2171. pranges[0].End = 256.0F;//到256结束(不含)
  2172. //6--计算直方图
  2173. Cv2.CalcHist(new Mat[1] { mat }, new int[] { 0 }, new Mat(), hist, dims, histSize, pranges);
  2174. int nHistSize = 256;
  2175. float maxY = 0;
  2176. int maxX = 0;
  2177. List<float> vs = new List<float>() { };
  2178. List<double> list = new List<double>() { };
  2179. for (int i = 1; i < nHistSize - 1; i++)
  2180. {
  2181. float y = hist.At<float>(i);
  2182. list.Add(y);
  2183. }
  2184. //maxX= GetHist(mat.Clone());
  2185. double[] dd = cubicSmooth7(list.ToArray(), list.Count());
  2186. List<double> maxList = new List<double>() { };
  2187. for (int i = 3; i < list.Count() - 1; i++)
  2188. {
  2189. double Y2 = dd[i];
  2190. double Y1 = dd[i - 3];
  2191. double angleOfLine = Math.Atan2((Y2 - Y1), 30000) * 180 / Math.PI;
  2192. maxList.Add(angleOfLine);
  2193. }
  2194. for (int i = maxList.Count() - 5; i > 10; i--)
  2195. {
  2196. double t1 = maxList[i];
  2197. double t2 = maxList[i + 1];
  2198. if (t1 - t2 < 0)
  2199. {
  2200. maxX = i;
  2201. break;
  2202. }
  2203. }
  2204. int max2 = list.FindIndex(s => s == list.Max());
  2205. //波峰
  2206. maxX = getMax(maxList, maxList.Count() - 15);
  2207. if (maxX > max2)
  2208. {
  2209. PointF p0 = new PointF(max2, Convert.ToInt32(dd[max2]));
  2210. //波峰顶点
  2211. PointF p1 = new PointF(maxX, Convert.ToInt32(dd[maxX]));
  2212. int pn = 0;
  2213. double maxD = 0;
  2214. //通过最远距离计算坡底
  2215. for (int i = max2; i < maxX; i++)
  2216. {
  2217. PointF p = new PointF(i, Convert.ToInt32(dd[i]));
  2218. double d = GetMinDistance(p0, p1, p);
  2219. if (maxD < d)
  2220. {
  2221. maxD = d;
  2222. pn = i;
  2223. }
  2224. }
  2225. return pn + (maxX - pn) / 2;
  2226. }
  2227. else
  2228. {
  2229. return maxX - 10;
  2230. }
  2231. }
  2232. /****点到直线的距离***
  2233. * 过点(x1,y1)和点(x2,y2)的直线方程为:KX -Y + (x2y1 - x1y2)/(x2-x1) = 0
  2234. * 设直线斜率为K = (y2-y1)/(x2-x1),C=(x2y1 - x1y2)/(x2-x1)
  2235. * 点P(x0,y0)到直线AX + BY +C =0DE 距离为:d=|Ax0 + By0 + C|/sqrt(A*A + B*B)
  2236. * 点(x3,y3)到经过点(x1,y1)和点(x2,y2)的直线的最短距离为:
  2237. * distance = |K*x3 - y3 + C|/sqrt(K*K + 1)
  2238. */
  2239. public static double GetMinDistance(PointF pt1, PointF pt2, PointF pt3)
  2240. {
  2241. double dis = 0;
  2242. if (pt1.X == pt2.X)
  2243. {
  2244. dis = Math.Abs(pt3.X - pt1.X);
  2245. return dis;
  2246. }
  2247. double lineK = (pt2.Y - pt1.Y) / (pt2.X - pt1.X);
  2248. double lineC = (pt2.X * pt1.Y - pt1.X * pt2.Y) / (pt2.X - pt1.X);
  2249. dis = Math.Abs(lineK * pt3.X - pt3.Y + lineC) / (Math.Sqrt(lineK * lineK + 1));
  2250. return dis;
  2251. }
  2252. /// <summary>
  2253. /// 数据平滑
  2254. /// </summary>
  2255. /// <param name="in1"></param>
  2256. /// <param name="N"></param>
  2257. /// <returns></returns>
  2258. private double[] quadraticSmooth5(double[] in1, int N)
  2259. {
  2260. double[] out1 = new double[in1.Length];
  2261. int i;
  2262. if (N < 5)
  2263. {
  2264. for (i = 0; i <= N - 1; i++)
  2265. {
  2266. out1[i] = in1[i];
  2267. }
  2268. }
  2269. else
  2270. {
  2271. out1[0] = (31.0 * in1[0] + 9.0 * in1[1] - 3.0 * in1[2] - 5.0 * in1[3] + 3.0 * in1[4]) / 35.0;
  2272. out1[1] = (9.0 * in1[0] + 13.0 * in1[1] + 12 * in1[2] + 6.0 * in1[3] - 5.0 * in1[4]) / 35.0;
  2273. for (i = 2; i <= N - 3; i++)
  2274. {
  2275. out1[i] = (-3.0 * (in1[i - 2] + in1[i + 2]) +
  2276. 12.0 * (in1[i - 1] + in1[i + 1]) + 17 * in1[i]) / 35.0;
  2277. }
  2278. out1[N - 2] = (9.0 * in1[N - 1] + 13.0 * in1[N - 2] + 12.0 * in1[N - 3] + 6.0 * in1[N - 4] - 5.0 * in1[N - 5]) / 35.0;
  2279. out1[N - 1] = (31.0 * in1[N - 1] + 9.0 * in1[N - 2] - 3.0 * in1[N - 3] - 5.0 * in1[N - 4] + 3.0 * in1[N - 5]) / 35.0;
  2280. }
  2281. return out1;
  2282. }
  2283. public double[] cubicSmooth7(double[] in1, int N)
  2284. {
  2285. double[] out1 = new double[in1.Length];
  2286. int i;
  2287. if (N < 7)
  2288. {
  2289. for (i = 0; i <= N - 1; i++)
  2290. {
  2291. out1[i] = in1[i];
  2292. }
  2293. }
  2294. else
  2295. {
  2296. out1[0] = (39.0 * in1[0] + 8.0 * in1[1] - 4.0 * in1[2] - 4.0 * in1[3] +
  2297. 1.0 * in1[4] + 4.0 * in1[5] - 2.0 * in1[6]) / 42.0;
  2298. out1[1] = (8.0 * in1[0] + 19.0 * in1[1] + 16.0 * in1[2] + 6.0 * in1[3] -
  2299. 4.0 * in1[4] - 7.0 * in1[5] + 4.0 * in1[6]) / 42.0;
  2300. out1[2] = (-4.0 * in1[0] + 16.0 * in1[1] + 19.0 * in1[2] + 12.0 * in1[3] +
  2301. 2.0 * in1[4] - 4.0 * in1[5] + 1.0 * in1[6]) / 42.0;
  2302. for (i = 3; i <= N - 4; i++)
  2303. {
  2304. out1[i] = (-2.0 * (in1[i - 3] + in1[i + 3]) +
  2305. 3.0 * (in1[i - 2] + in1[i + 2]) +
  2306. 6.0 * (in1[i - 1] + in1[i + 1]) + 7.0 * in1[i]) / 21.0;
  2307. }
  2308. out1[N - 3] = (-4.0 * in1[N - 1] + 16.0 * in1[N - 2] + 19.0 * in1[N - 3] +
  2309. 12.0 * in1[N - 4] + 2.0 * in1[N - 5] - 4.0 * in1[N - 6] + 1.0 * in1[N - 7]) / 42.0;
  2310. out1[N - 2] = (8.0 * in1[N - 1] + 19.0 * in1[N - 2] + 16.0 * in1[N - 3] +
  2311. 6.0 * in1[N - 4] - 4.0 * in1[N - 5] - 7.0 * in1[N - 6] + 4.0 * in1[N - 7]) / 42.0;
  2312. out1[N - 1] = (39.0 * in1[N - 1] + 8.0 * in1[N - 2] - 4.0 * in1[N - 3] -
  2313. 4.0 * in1[N - 4] + 1.0 * in1[N - 5] + 4.0 * in1[N - 6] - 2.0 * in1[N - 7]) / 42.0;
  2314. }
  2315. return out1;
  2316. }
  2317. public double[] quadraticSmooth7(double[] in1, int N)
  2318. {
  2319. double[] out1 = new double[in1.Length];
  2320. int i;
  2321. if (N < 7)
  2322. {
  2323. for (i = 0; i <= N - 1; i++)
  2324. {
  2325. out1[i] = in1[i];
  2326. }
  2327. }
  2328. else
  2329. {
  2330. out1[0] = (32.0 * in1[0] + 15.0 * in1[1] + 3.0 * in1[2] - 4.0 * in1[3] -
  2331. 6.0 * in1[4] - 3.0 * in1[5] + 5.0 * in1[6]) / 42.0;
  2332. out1[1] = (5.0 * in1[0] + 4.0 * in1[1] + 3.0 * in1[2] + 2.0 * in1[3] +
  2333. in1[4] - in1[6]) / 14.0;
  2334. out1[2] = (1.0 * in1[0] + 3.0 * in1[1] + 4.0 * in1[2] + 4.0 * in1[3] +
  2335. 3.0 * in1[4] + 1.0 * in1[5] - 2.0 * in1[6]) / 14.0;
  2336. for (i = 3; i <= N - 4; i++)
  2337. {
  2338. out1[i] = (-2.0 * (in1[i - 3] + in1[i + 3]) +
  2339. 3.0 * (in1[i - 2] + in1[i + 2]) +
  2340. 6.0 * (in1[i - 1] + in1[i + 1]) + 7.0 * in1[i]) / 21.0;
  2341. }
  2342. out1[N - 3] = (1.0 * in1[N - 1] + 3.0 * in1[N - 2] + 4.0 * in1[N - 3] +
  2343. 4.0 * in1[N - 4] + 3.0 * in1[N - 5] + 1.0 * in1[N - 6] - 2.0 * in1[N - 7]) / 14.0;
  2344. out1[N - 2] = (5.0 * in1[N - 1] + 4.0 * in1[N - 2] + 3.0 * in1[N - 3] +
  2345. 2.0 * in1[N - 4] + in1[N - 5] - in1[N - 7]) / 14.0;
  2346. out1[N - 1] = (32.0 * in1[N - 1] + 15.0 * in1[N - 2] + 3.0 * in1[N - 3] -
  2347. 4.0 * in1[N - 4] - 6.0 * in1[N - 5] - 3.0 * in1[N - 6] + 5.0 * in1[N - 7]) / 42.0;
  2348. }
  2349. return out1;
  2350. }
  2351. /// <summary>
  2352. /// 获取直方图
  2353. /// </summary>
  2354. /// <returns></returns>
  2355. private int GetHist(Mat srcImage)
  2356. {
  2357. Mat hist = new Mat();
  2358. Mat Gaos = new Mat();
  2359. Cv2.GaussianBlur(srcImage, Gaos, new OpenCvSharp.Size(7, 7), 0);
  2360. //设置计算直方图的维度
  2361. int dims = 1;
  2362. //直方图的每一个维度的柱条的数目(就是将数值分组,共有多少组)
  2363. int[] histSize = { 255 };
  2364. Rangef[] pranges = new Rangef[1];//一个通道,范围
  2365. pranges[0].Start = 0.0F;//从0开始(含)
  2366. pranges[0].End = 256.0F;//到256结束(不含)
  2367. //6--计算直方图
  2368. Cv2.CalcHist(new Mat[1] { Gaos }, new int[] { 0 }, new Mat(), hist, dims, histSize, pranges);
  2369. Mat drawImage = Mat.Zeros(new OpenCvSharp.Size(256, 256), MatType.CV_8UC3);
  2370. double min = 0;
  2371. double max = 0;
  2372. Cv2.MinMaxLoc(hist, out min, out max);
  2373. for (int i = 0; i < 256; i++)
  2374. {
  2375. int value = Convert.ToInt32(Math.Round(hist.At<float>(i) * 256 * 0.9 / max, MidpointRounding.AwayFromZero));
  2376. Cv2.Line(drawImage, new OpenCvSharp.Point(i, drawImage.Rows - 1), new OpenCvSharp.Point(i, drawImage.Rows - 1 - value), new Scalar(255, 0, 0));
  2377. }
  2378. //灰度图
  2379. Cv2.CvtColor(drawImage, drawImage, ColorConversionCodes.BGR2GRAY);
  2380. Mat g_bwImage = new Mat();
  2381. //图像二值化
  2382. Cv2.Threshold(drawImage, g_bwImage, 0, 255, ThresholdTypes.Binary);
  2383. OpenCvSharp.Point[][] contours = new OpenCvSharp.Point[][] { };
  2384. HierarchyIndex[] hierarchyIndex = new HierarchyIndex[] { };
  2385. //轮廓
  2386. Cv2.FindContours(g_bwImage, out contours, out hierarchyIndex, RetrievalModes.External, ContourApproximationModes.ApproxNone);
  2387. InputArray contoursAll = InputArray.Create(contours[0]);
  2388. List<OpenCvSharp.Point> outArr = new List<OpenCvSharp.Point>();
  2389. OutputArray hull = OutputArray.Create(outArr);
  2390. Cv2.ConvexHull(contoursAll, hull, true);
  2391. int retint = 0;
  2392. for (int i = 0; i < outArr.Count; i++)
  2393. {
  2394. if (outArr[i].X > 230)
  2395. {
  2396. continue;
  2397. }
  2398. else if (outArr[i].X < 20)
  2399. {
  2400. continue;
  2401. }
  2402. else if (retint < outArr[i].X)
  2403. {
  2404. retint = outArr[i].X;
  2405. }
  2406. }
  2407. // Cv2.ImShow("【直方图】", drawImage);
  2408. return retint;
  2409. }
  2410. /// <summary>
  2411. /// 获取凸包
  2412. /// </summary>
  2413. /// <param name="src"></param>
  2414. private void convexity_defects(Mat src)
  2415. {
  2416. Mat src_copy = src.Clone();
  2417. Mat threshold_output = new Mat(), src_gray = new Mat();
  2418. OpenCvSharp.Point[][] contours = new OpenCvSharp.Point[][] { };
  2419. HierarchyIndex[] hierarchyIndex = new HierarchyIndex[] { };
  2420. List<Vec4i> hierarchy;
  2421. Cv2.CvtColor(src_copy, src_gray, ColorConversionCodes.BGR2GRAY);
  2422. Cv2.Threshold(src_gray, threshold_output, 0, 255, ThresholdTypes.Binary);
  2423. Cv2.FindContours(threshold_output, out contours, out hierarchyIndex, RetrievalModes.Tree, ContourApproximationModes.ApproxSimple);
  2424. List<int> hullsI = new List<int>() { };
  2425. List<Vec4i> defect = new List<Vec4i>() { };
  2426. InputArray contoursAll = InputArray.Create(contours[0]);
  2427. List<OpenCvSharp.Point> outArr = new List<OpenCvSharp.Point>();
  2428. OutputArray hull = OutputArray.Create(outArr);
  2429. OutputArray hulls = OutputArray.Create(hullsI);
  2430. OutputArray defects = OutputArray.Create(defect);
  2431. Cv2.ConvexHull(contoursAll, hull, false);
  2432. // find int type hull
  2433. Cv2.ConvexHull(contoursAll, hulls, false);
  2434. InputArray hullsi = InputArray.Create(hullsI);
  2435. // get convexity defects
  2436. Cv2.ConvexityDefects(contoursAll, hullsi, defects);
  2437. /// Draw contours + hull results
  2438. Mat drawing = Mat.Zeros(threshold_output.Size(), MatType.CV_8UC3);
  2439. Scalar color = new Scalar(210, 50, 255);
  2440. Cv2.DrawContours(drawing, contours, 0, color, -1);
  2441. Cv2.DrawContours(drawing, new OpenCvSharp.Point[][] { outArr.ToArray() }, 0, color, -1);
  2442. // draw defects
  2443. int count = contours[0].Count();
  2444. foreach (var item in defect)
  2445. {
  2446. int startidx = item[0];
  2447. OpenCvSharp.Point ptStart = contours[0][startidx]; // point of the contour where the defect begins
  2448. int endidx = item[1];
  2449. OpenCvSharp.Point ptEnd = contours[0][endidx]; // point of the contour where the defect ends
  2450. int faridx = item[2];
  2451. OpenCvSharp.Point ptFar = contours[0][faridx];// the farthest from the convex hull point within the defect
  2452. int depth = item[3] / 256; // distance between the farthest point and the convex hull
  2453. if (depth > 2 && depth < 500)
  2454. {
  2455. Cv2.Line(drawing, ptStart, ptFar, new Scalar(0, 255, 0), 2);
  2456. Cv2.Line(drawing, ptEnd, ptFar, new Scalar(0, 255, 0), 2);
  2457. Cv2.Circle(drawing, ptStart, 4, new Scalar(255, 0, 0), 2);
  2458. Cv2.Circle(drawing, ptEnd, 4, new Scalar(255, 0, 0), 2);
  2459. Cv2.Circle(drawing, ptFar, 4, new Scalar(100, 0, 255), 2);
  2460. }
  2461. }
  2462. Cv2.ImShow("Hull demo", drawing);
  2463. }
  2464. #endregion
  2465. #region 开裂球
  2466. /// <summary>
  2467. /// 忽略开裂球,设为开裂球,设为普通球
  2468. /// </summary>
  2469. /// <returns></returns>
  2470. public List<List<int>> DeleteBall(List<PointF> pointFs, List<PointF> KpointFs, List<PointF> PpointFs)
  2471. {
  2472. List<List<int>> data = new List<List<int>>() { };
  2473. ProgressThreadProcClass procClass = new ProgressThreadProcClass();
  2474. int itemCount = 100;
  2475. Mat newMat = new Mat();
  2476. Bitmap bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
  2477. ProgressThreadProcClass.IFileTransferProgressEvents progressEvents = new ProgressThreadProcClass.IFileTransferProgressEvents();
  2478. System.Threading.ThreadStart copyThreadProc =
  2479. delegate ()
  2480. {
  2481. try
  2482. {
  2483. action.Lists.Add(new Args() { Key = "SelPointFs", Value = -1 });
  2484. action.Lists.Add(new Args() { Key = "imageTypes", Value = 14 });
  2485. action.Lists.Add(new Args() { Key = "CreackBallPointFs", Value = pointFs });
  2486. action.Lists.Add(new Args() { Key = "CreackBallPointFsK", Value = KpointFs });
  2487. action.Lists.Add(new Args() { Key = "CreackBallPointFsP", Value = PpointFs });
  2488. newMat = this.PerformProcessGetdata(LunkMat, OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap), out data);
  2489. }
  2490. catch (Exception e)
  2491. {
  2492. }
  2493. finally
  2494. {
  2495. progressEvents.EndOperation(OperationResult.Finished);
  2496. }
  2497. };
  2498. procClass.StartProgressAction(/*currentForm*/parent, itemCount, copyThreadProc, progressEvents, null);
  2499. if (bmc != null) { bmc.data = data; bmc.isedit = true; }
  2500. if (bc != null) { bc.data = data; bc.isedit = true; }
  2501. documentWorkspace.PhaseModels[0].mat = newMat;
  2502. documentWorkspace.Refresh();
  2503. return data;
  2504. }
  2505. /// <summary>
  2506. /// 绘制轮廓开裂球
  2507. /// </summary>
  2508. /// <returns></returns>
  2509. public List<List<int>> DrwLunKuoLie(List<List<PointF>> pointFs, List<PointF> KaiPointFs, List<PointF> PuPointFs)
  2510. {
  2511. lineList_ball = pointFs;
  2512. kailie_ball = KaiPointFs;
  2513. putong_ball = PuPointFs;
  2514. List<List<int>> data = new List<List<int>>() { };
  2515. Bitmap bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
  2516. Mat newMat = new Mat();
  2517. ProgressThreadProcClass procClass = new ProgressThreadProcClass();
  2518. int itemCount = 100;
  2519. ProgressThreadProcClass.IFileTransferProgressEvents progressEvents = new ProgressThreadProcClass.IFileTransferProgressEvents();
  2520. System.Threading.ThreadStart copyThreadProc =
  2521. delegate ()
  2522. {
  2523. try
  2524. {
  2525. newMat = getKong(bitmap, out data);
  2526. }
  2527. catch (Exception)
  2528. {
  2529. }
  2530. finally
  2531. {
  2532. progressEvents.EndOperation(OperationResult.Finished);
  2533. }
  2534. };
  2535. procClass.StartProgressAction(/*currentForm*/parent, itemCount, copyThreadProc, progressEvents, null);
  2536. // Mat newMat = getKong(bitmap, out data);
  2537. if (bmc != null) { bmc.data = data; bmc.isedit = true; }
  2538. if (bc != null) { bc.data = data; bc.isedit = true; }
  2539. documentWorkspace.PhaseModels[0].mat = newMat;
  2540. documentWorkspace.Refresh();
  2541. return data;
  2542. }
  2543. /// <summary>
  2544. /// 绘制轮廓开裂球
  2545. /// </summary>
  2546. /// <returns></returns>
  2547. public List<List<int>> DrwLunKuoLie1(List<List<PointF>> pointFs, List<PointF> KaiPointFs, List<PointF> PuPointFs)
  2548. {
  2549. lineList_ball = pointFs;
  2550. kailie_ball = KaiPointFs;
  2551. putong_ball = PuPointFs;
  2552. List<List<int>> data = new List<List<int>>() { };
  2553. Bitmap bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
  2554. Mat newMat = ReGetKong(bitmap, out data);
  2555. if (bmc != null) { bmc.data = data; bmc.isedit = true; }
  2556. if (bc != null) { bc.data = data; bc.isedit = true; }
  2557. documentWorkspace.PhaseModels[0].mat = newMat;
  2558. documentWorkspace.Refresh();
  2559. return data;
  2560. }
  2561. /// <summary>
  2562. /// 选择开裂球
  2563. /// </summary>
  2564. /// <returns></returns>
  2565. public void DrwLunKuoLie1Selected(int select)
  2566. {
  2567. List<List<int>> data = new List<List<int>>() { };
  2568. Bitmap bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
  2569. action.Lists.Add(new Args() { Key = "SelPointFs", Value = select });
  2570. Mat newMat = this.PerformProcessGetdata(OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap), out data);
  2571. documentWorkspace.PhaseModels[0].mat = newMat;
  2572. documentWorkspace.Refresh();
  2573. }
  2574. //所有点
  2575. Dictionary<int, List<OpenCvSharp.Point>> particlePixles = new Dictionary<int, List<OpenCvSharp.Point>>();
  2576. List<int> relit = new List<int>();
  2577. Mat g_srcImage = new Mat();
  2578. Mat temp = new Mat();
  2579. Vec4b vec4B = new Vec4b(255, 0, 0, 255);
  2580. Vec4b vec4B1 = new Vec4b(0, 0, 255, 255);
  2581. /// <summary>
  2582. /// 获取开裂球
  2583. /// </summary>
  2584. /// <param name="img"></param>
  2585. /// <returns></returns>
  2586. private Mat getKong(Bitmap img, out List<List<int>> outdata)
  2587. {
  2588. particlePixles = new Dictionary<int, List<OpenCvSharp.Point>>();
  2589. relit = new List<int>();
  2590. g_srcImage = new Mat();
  2591. temp = new Mat();
  2592. outdata = new List<List<int>>() { };
  2593. Mat M = OpenCvSharp.Extensions.BitmapConverter.ToMat(img);
  2594. //M.ConvertTo(g_srcImage, MatType.CV_8UC3);
  2595. Cv2.CvtColor(M, g_srcImage, ColorConversionCodes.BGRA2BGR);
  2596. if (lineList_ball.Count > 0)
  2597. {
  2598. for (int line = 0; line < lineList_ball.Count; line++)
  2599. {
  2600. List<PointF> pointList = lineList_ball[line];
  2601. for (int i = 0; i < pointList.Count - 1; i++)
  2602. {
  2603. Cv2.Line(g_srcImage, new OpenCvSharp.Point() { X = (int)pointList[i].X, Y = (int)pointList[i].Y }, new OpenCvSharp.Point() { X = (int)pointList[i + 1].X, Y = (int)pointList[i + 1].Y }, new Scalar(0, 0, 0), 5);
  2604. }
  2605. }
  2606. }
  2607. //调试方便
  2608. // Cv2.Resize(g_srcImage, g_srcImage,new OpenCvSharp.Size(g_srcImage.Cols / 3, g_srcImage.Rows / 3), (0.0), (0.0), OpenCvSharp.InterpolationFlags.Area);
  2609. Mat gray = new Mat();
  2610. Mat binary = new Mat();
  2611. Mat shifted = new Mat(M.Size(), MatType.CV_8UC3);
  2612. //均值漂移 滤波
  2613. // Cv2.PyrMeanShiftFiltering(g_srcImage, shifted, 21, 51);
  2614. Cv2.GaussianBlur(g_srcImage, shifted, new OpenCvSharp.Size(15, 15), 0);
  2615. //灰度图
  2616. Cv2.CvtColor(shifted, gray, ColorConversionCodes.BGR2GRAY);
  2617. //二值化
  2618. double otsu = Cv2.Threshold(gray, binary, 100, 200, ThresholdTypes.Binary/*.Otsu*/);
  2619. // distance transform
  2620. Mat dist = new Mat();
  2621. Cv2.DistanceTransform(binary, dist, DistanceTypes.L2, DistanceMaskSize.Mask3);
  2622. //归一化数据
  2623. Cv2.Normalize(dist, dist, 0, 1, NormTypes.MinMax);
  2624. // binary
  2625. Cv2.Threshold(dist, dist, 0.4, 1, ThresholdTypes.Binary);
  2626. // markers
  2627. Mat dist_m = new Mat();
  2628. dist.ConvertTo(dist_m, MatType.CV_8UC1);
  2629. OpenCvSharp.Point[][] contours = new OpenCvSharp.Point[][] { };
  2630. HierarchyIndex[] hierarchyIndex = new HierarchyIndex[] { };
  2631. Cv2.FindContours(dist_m, out contours, out hierarchyIndex, RetrievalModes.External, ContourApproximationModes.ApproxNone);
  2632. // create markers
  2633. Mat markers = Mat.Zeros(g_srcImage.Size(), MatType.CV_32SC1);
  2634. for (int t = 0; t < contours.Length; t++)
  2635. {
  2636. Cv2.DrawContours(markers, contours, t, new Scalar(t + 1), -1);
  2637. }
  2638. // Cv2.ImShow("分割后", markers);
  2639. Cv2.Circle(markers, new OpenCvSharp.Point(5, 5), 30, new Scalar(255), -1);
  2640. //形体学操作 去掉干扰
  2641. InputArray kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(3, 3), new OpenCvSharp.Point(-1, -1));
  2642. Cv2.MorphologyEx(g_srcImage, g_srcImage, MorphTypes.Erode, kernel);
  2643. Cv2.Watershed(g_srcImage, markers);
  2644. // 颜色填充与最终显示
  2645. int index = 0;
  2646. for (int row = 0; row < markers.Rows; row++)
  2647. {
  2648. for (int col = 0; col < markers.Cols; col++)
  2649. {
  2650. index = markers.At<int>(row, col);
  2651. if (index > 0 && index <= contours.Length)
  2652. {
  2653. if (particlePixles.ContainsKey(index))
  2654. {
  2655. particlePixles[index].Add(new OpenCvSharp.Point(col, row));
  2656. }
  2657. else
  2658. {
  2659. List<OpenCvSharp.Point> Pixles = new List<OpenCvSharp.Point>();
  2660. Pixles.Add(new OpenCvSharp.Point(col, row));
  2661. particlePixles.Add(index, Pixles);
  2662. }
  2663. }
  2664. }
  2665. }
  2666. int k = 0;
  2667. foreach (var item in particlePixles)
  2668. {
  2669. if (item.Value.Count > 99999)
  2670. {
  2671. k = item.Key;
  2672. break;
  2673. }
  2674. }
  2675. particlePixles.Remove(k);
  2676. //temp = Adjust.BaseImage.BaseTools.MergeMatFromMatArr(temp, vec4B);
  2677. int q = 0;
  2678. int iskailie = 0;
  2679. temp = new Mat(g_srcImage.Rows, g_srcImage.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 0));
  2680. int index1 = 0;
  2681. foreach (var item in particlePixles)
  2682. {
  2683. // 将轮廓转为矩形框 , 这个最大的矩形为感兴趣的图像
  2684. Rect rect = Cv2.BoundingRect(item.Value);
  2685. List<OpenCvSharp.Point> pixel = item.Value;
  2686. Mat particle = g_srcImage[rect];
  2687. Mat back = particle.Clone();
  2688. //Mat forwrit = M[rect];
  2689. //Mat small = forwrit.Clone();
  2690. //int n = 30;
  2691. //float MaxCG = 5.5f;
  2692. //Mat dst1 = myACE(small, n, MaxCG);
  2693. //Mat element = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(5, 5));
  2694. //Cv2.MorphologyEx(dst1, dst1, MorphTypes.BlackHat, element);
  2695. //Cv2.GaussianBlur(dst1, dst1, new OpenCvSharp.Size(3, 3), 0);
  2696. //Cv2.ImWrite("E://1/" + index1++.ToString() + ".jpg", dst1);
  2697. ////for (int i = 0; i < small.Cols; i++)
  2698. ////{
  2699. //// for (int j = 0; j < small.Rows; j++)
  2700. //// {
  2701. //// OpenCvSharp.Point pp = new OpenCvSharp.Point() { X=i+ rect.X, Y=j+ rect.Y };
  2702. //// if (pixel.Contains(pp))
  2703. //// {
  2704. //// continue;
  2705. //// }
  2706. //// small.Set<Vec3b>(j, i, new Vec3b(255, 0, 0));
  2707. //// }
  2708. ////}
  2709. //// Cv2.ImWrite("E:/ballcut/test" + index1.ToString() + ".jpg", small);
  2710. long aveg = 0;
  2711. long aveb = 0;
  2712. long aver = 0;
  2713. foreach (var pt in pixel)
  2714. {
  2715. if (kailie_ball.Count > 0)
  2716. {
  2717. PointF p = new PointF() { X = pt.X, Y = pt.Y };
  2718. if (kailie_ball.Contains(p))
  2719. {
  2720. iskailie = 1;
  2721. break;
  2722. }
  2723. }
  2724. if (putong_ball.Count > 0)
  2725. {
  2726. PointF p = new PointF() { X = pt.X, Y = pt.Y };
  2727. if (putong_ball.Contains(p))
  2728. {
  2729. iskailie = 2;
  2730. break;
  2731. }
  2732. }
  2733. aveg += particle.At<Vec3b>(pt.Y - rect.Y, pt.X - rect.X)[0];
  2734. aveb += particle.At<Vec3b>(pt.Y - rect.Y, pt.X - rect.X)[1];
  2735. aver += particle.At<Vec3b>(pt.Y - rect.Y, pt.X - rect.X)[2];
  2736. }
  2737. int ret = 0;
  2738. if (iskailie == 1)
  2739. {
  2740. ret = 1;
  2741. }
  2742. else if (iskailie == 2)
  2743. {
  2744. ret = 0;
  2745. }
  2746. else
  2747. {
  2748. aveg = aveg / pixel.Count;
  2749. aveb = aveb / pixel.Count;
  2750. aver = aver / pixel.Count;
  2751. for (int i = 0; i < back.Cols; i++)
  2752. {
  2753. for (int j = 0; j < back.Rows; j++)
  2754. {
  2755. back.Set<Vec3b>(j, i, new Vec3b((byte)aveg, (byte)aveb, (byte)aver));
  2756. }
  2757. }
  2758. foreach (var pt in pixel)
  2759. {
  2760. back.Set<Vec3b>(pt.Y - rect.Y, pt.X - rect.X, particle.At<Vec3b>(pt.Y - rect.Y, pt.X - rect.X));
  2761. }
  2762. ret = GetSplit2(back);
  2763. relit.Add(ret);
  2764. }
  2765. if (ret == 1)
  2766. {
  2767. Cv2.DrawContours(temp, new List<List<OpenCvSharp.Point>>() { item.Value }, 0, new Scalar(0, 0, 255, 255), 2);
  2768. }
  2769. else if (ret == 0)
  2770. {
  2771. Cv2.DrawContours(temp, new List<List<OpenCvSharp.Point>>() { item.Value }, 0, new Scalar(255, 0, 0, 255), 2);
  2772. }
  2773. double area = Cv2.ContourArea(item.Value);
  2774. int x = rect.X;
  2775. int y = rect.Y;
  2776. int width = rect.Width;
  2777. int height = rect.Height;
  2778. if (kailie_ball.Count > 0)
  2779. {
  2780. for (int i = 0; i < kailie_ball.Count; i++)
  2781. {
  2782. double px = kailie_ball[i].X;
  2783. double py = kailie_ball[i].Y;
  2784. if (px > x && px < (x + width) && py > y && py < (y + height))
  2785. {
  2786. ret = 1;
  2787. relit[index1] = 1;
  2788. break;
  2789. }
  2790. }
  2791. }
  2792. if (putong_ball.Count > 0)
  2793. {
  2794. for (int i = 0; i < putong_ball.Count; i++)
  2795. {
  2796. double px = putong_ball[i].X;
  2797. double py = putong_ball[i].Y;
  2798. if (px > x && px < (x + width) && py > y && py < (y + height))
  2799. {
  2800. ret = 0;
  2801. relit[index1] = 0;
  2802. break;
  2803. }
  2804. }
  2805. }
  2806. List<int> po = new List<int>() { x, y, width, height, (int)area, ret };
  2807. outdata.Add(po);
  2808. index1++;
  2809. }
  2810. Mat temp1 = new Mat();
  2811. Cv2.Erode(temp, temp1, null);
  2812. temp = temp - temp1;
  2813. return temp;
  2814. }
  2815. private Mat ReGetKong(Bitmap img, out List<List<int>> outdata)
  2816. {
  2817. outdata = new List<List<int>>() { };
  2818. if (particlePixles.Count == 0)
  2819. {
  2820. return null;
  2821. }
  2822. temp = new Mat(g_srcImage.Rows, g_srcImage.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 0));
  2823. int index = 0;
  2824. foreach (var item in particlePixles)
  2825. {
  2826. // 将轮廓转为矩形框 , 这个最大的矩形为感兴趣的图像
  2827. Rect rect = Cv2.BoundingRect(item.Value);
  2828. List<OpenCvSharp.Point> pixel = item.Value;
  2829. Mat particle = g_srcImage[rect];
  2830. int ret = relit[index];
  2831. double area = Cv2.ContourArea(item.Value);
  2832. int x = rect.X;
  2833. int y = rect.Y;
  2834. int width = rect.Width;
  2835. int height = rect.Height;
  2836. if (kailie_ball.Count > 0)
  2837. {
  2838. for (int i = 0; i < kailie_ball.Count; i++)
  2839. {
  2840. double px = kailie_ball[i].X;
  2841. double py = kailie_ball[i].Y;
  2842. if (px > x && px < (x + width) && py > y && py < (y + height))
  2843. {
  2844. ret = 1;
  2845. relit[index] = 1;
  2846. break;
  2847. }
  2848. }
  2849. }
  2850. if (putong_ball.Count > 0)
  2851. {
  2852. for (int i = 0; i < putong_ball.Count; i++)
  2853. {
  2854. double px = putong_ball[i].X;
  2855. double py = putong_ball[i].Y;
  2856. if (px > x && px < (x + width) && py > y && py < (y + height))
  2857. {
  2858. ret = 0;
  2859. relit[index] = 0;
  2860. break;
  2861. }
  2862. }
  2863. }
  2864. if (selectPointFs != null)
  2865. {
  2866. double px = selectPointFs.X;
  2867. double py = selectPointFs.Y;
  2868. if (px == x && py == y)
  2869. {
  2870. ret = 2;
  2871. }
  2872. }
  2873. index++;
  2874. if (ret == 1)
  2875. {
  2876. Cv2.DrawContours(temp, new List<List<OpenCvSharp.Point>>() { item.Value }, 0, new Scalar(0, 0, 255, 255), 2);
  2877. }
  2878. else if (ret == 0)
  2879. {
  2880. Cv2.DrawContours(temp, new List<List<OpenCvSharp.Point>>() { item.Value }, 0, new Scalar(255, 0, 0, 255), 2);
  2881. }
  2882. else if (ret == 2)
  2883. {
  2884. Cv2.DrawContours(temp, new List<List<OpenCvSharp.Point>>() { item.Value }, 0, new Scalar(255, 255, 0, 255), 2);
  2885. }
  2886. List<int> po = new List<int>() { x, y, width, height, (int)area, ret };
  2887. outdata.Add(po);
  2888. }
  2889. Mat temp1 = new Mat();
  2890. Cv2.Erode(temp, temp1, null);
  2891. temp = temp - temp1;
  2892. return temp;
  2893. }
  2894. private Mat ReGetSelect(Bitmap img)
  2895. {
  2896. if (particlePixles.Count == 0)
  2897. {
  2898. return null;
  2899. }
  2900. temp = new Mat(g_srcImage.Rows, g_srcImage.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 0));
  2901. int index = 0;
  2902. foreach (var item in particlePixles)
  2903. {
  2904. // 将轮廓转为矩形框 , 这个最大的矩形为感兴趣的图像
  2905. Rect rect = Cv2.BoundingRect(item.Value);
  2906. List<OpenCvSharp.Point> pixel = item.Value;
  2907. Mat particle = g_srcImage[rect];
  2908. int ret = relit[index];
  2909. double area = Cv2.ContourArea(item.Value);
  2910. int x = rect.X;
  2911. int y = rect.Y;
  2912. int width = rect.Width;
  2913. int height = rect.Height;
  2914. if (kailie_ball.Count > 0)
  2915. {
  2916. for (int i = 0; i < kailie_ball.Count; i++)
  2917. {
  2918. double px = kailie_ball[i].X;
  2919. double py = kailie_ball[i].Y;
  2920. if (px > x && px < (x + width) && py > y && py < (y + height))
  2921. {
  2922. ret = 1;
  2923. relit[index] = 1;
  2924. break;
  2925. }
  2926. }
  2927. }
  2928. if (putong_ball.Count > 0)
  2929. {
  2930. for (int i = 0; i < putong_ball.Count; i++)
  2931. {
  2932. double px = putong_ball[i].X;
  2933. double py = putong_ball[i].Y;
  2934. if (px > x && px < (x + width) && py > y && py < (y + height))
  2935. {
  2936. ret = 0;
  2937. relit[index] = 0;
  2938. break;
  2939. }
  2940. }
  2941. }
  2942. if (selectPointFs != null)
  2943. {
  2944. double px = selectPointFs.X;
  2945. double py = selectPointFs.Y;
  2946. if (px == x && py == y)
  2947. {
  2948. ret = 2;
  2949. }
  2950. }
  2951. index++;
  2952. if (ret == 1)
  2953. {
  2954. Cv2.DrawContours(temp, new List<List<OpenCvSharp.Point>>() { item.Value }, 0, new Scalar(0, 0, 255, 255), 2);
  2955. }
  2956. else if (ret == 0)
  2957. {
  2958. Cv2.DrawContours(temp, new List<List<OpenCvSharp.Point>>() { item.Value }, 0, new Scalar(255, 0, 0, 255), 2);
  2959. }
  2960. else if (ret == 2)
  2961. {
  2962. Cv2.DrawContours(temp, new List<List<OpenCvSharp.Point>>() { item.Value }, 0, new Scalar(255, 255, 0, 255), 2);
  2963. }
  2964. }
  2965. Mat temp1 = new Mat();
  2966. Cv2.Erode(temp, temp1, null);
  2967. temp = temp - temp1;
  2968. return temp;
  2969. }
  2970. private int GetSplit2(Mat src)
  2971. {
  2972. Mat shifted = new Mat(), gray = new Mat(), binary = new Mat(), dist;
  2973. //Cv2.GaussianBlur(src, shifted, new OpenCvSharp.Size(3, 3), 0);
  2974. Cv2.PyrMeanShiftFiltering(src, shifted, 10, 18); //模糊细节,这个参数由颗粒的大小确定
  2975. Cv2.CvtColor(shifted, gray, ColorConversionCodes.BGR2GRAY);
  2976. Mat element = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(5, 5));
  2977. Cv2.MorphologyEx(gray, gray, MorphTypes.TopHat, element);
  2978. Cv2.Threshold(gray, binary, 0, 255, ThresholdTypes.Binary | ThresholdTypes.Otsu);
  2979. Mat element1 = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(3, 3));
  2980. Cv2.MorphologyEx(binary, binary, MorphTypes.Open, element1);
  2981. for (int i = 0; i < 4; i++)
  2982. Cv2.MorphologyEx(binary, binary, MorphTypes.Dilate, element1);
  2983. int height = src.Rows;
  2984. int width = src.Cols;
  2985. OpenCvSharp.Point[][] contours = new OpenCvSharp.Point[][] { };
  2986. HierarchyIndex[] hierarchyIndex = new HierarchyIndex[] { };
  2987. Cv2.FindContours(binary, out contours, out hierarchyIndex, RetrievalModes.External, ContourApproximationModes.ApproxSimple, new OpenCvSharp.Point(0, 0));
  2988. if (contours.Length == 0)
  2989. {
  2990. return -1;
  2991. }
  2992. List<OpenCvSharp.Point> arrAll = new List<OpenCvSharp.Point>();
  2993. for (int t = 0; t < contours.Length; t++)
  2994. {
  2995. foreach (var item in contours[t])
  2996. {
  2997. arrAll.Add(item);
  2998. }
  2999. }
  3000. InputArray contoursAll = InputArray.Create(arrAll);
  3001. List<OpenCvSharp.Point> outArr = new List<OpenCvSharp.Point>();
  3002. List<OpenCvSharp.Point> hullpoint = new List<OpenCvSharp.Point>();
  3003. OutputArray hull = OutputArray.Create(outArr);
  3004. Cv2.ConvexHull(contoursAll, hull, true);
  3005. int hullcount = outArr.Count;
  3006. OpenCvSharp.Point point0 = outArr[hullcount - 1];
  3007. hullpoint.Add(point0);
  3008. for (int i = 0; i < hullcount; i++)
  3009. {
  3010. OpenCvSharp.Point point = outArr[i];
  3011. Cv2.Line(binary, point0, point, new Scalar(255, 255, 255));
  3012. point0 = point;
  3013. hullpoint.Add(point0);
  3014. }
  3015. bool flag = false;
  3016. for (int t = 0; t < contours.Length; t++)
  3017. {
  3018. int size = contours[t].Length;
  3019. if (size < 10)
  3020. {
  3021. continue;
  3022. }
  3023. Rect r = Cv2.BoundingRect(contours[t]);
  3024. float rcX = r.X + r.Width / 2;
  3025. float rcY = r.Y + r.Height / 2;
  3026. double d = Cv2.PointPolygonTest(hullpoint, new Point2f(rcX, rcY), true);
  3027. if ((d == 0) || (d < 0) || ((d < 15) && (d > 0))) //在凸包边缘上,在凸包的外部,在凸包的内部
  3028. {
  3029. continue;
  3030. }
  3031. else
  3032. {
  3033. flag = true;
  3034. break;
  3035. }
  3036. }
  3037. if (flag == true)
  3038. {
  3039. return 1;
  3040. }
  3041. return 0;
  3042. }
  3043. #region 赵天宇算法
  3044. public void test(Mat src)
  3045. {
  3046. Mat dst = new Mat();
  3047. //1:因为霍夫圆检测对噪声比较敏感,所以首先对图像做一个中值滤波或高斯滤波(噪声如果没有可以不做)
  3048. Mat m1 = new Mat();
  3049. Cv2.MedianBlur(src, m1, 3); // ksize必须大于1且是奇数
  3050. //2:转为灰度图像
  3051. Mat m2 = m1.Clone();
  3052. // m1.Release();
  3053. Cv2.CvtColor(m1, m2, ColorConversionCodes.BGR2GRAY);
  3054. CircleSegment[] cs = Cv2.HoughCircles(m2, HoughMethods.Gradient, 1, 130, 60, 25, 35, 80);
  3055. m2.Release();
  3056. src.CopyTo(dst);
  3057. //大圆
  3058. for (int i = 0; i < cs.Count(); i++)
  3059. {
  3060. //画圆
  3061. Cv2.Circle(dst, (int)cs[i].Center.X, (int)cs[i].Center.Y, (int)cs[i].Radius, new Scalar(0, 0, 255), 2, LineTypes.AntiAlias);
  3062. //加强圆心显示
  3063. Cv2.Circle(dst, (int)cs[i].Center.X, (int)cs[i].Center.Y, 3, new Scalar(0, 0, 255), 2, LineTypes.AntiAlias);
  3064. }
  3065. using (new Window("OutputImage", WindowMode.Normal, dst))
  3066. using (new Window("InputImage", WindowMode.Normal, src))
  3067. {
  3068. Cv2.WaitKey(0);
  3069. }
  3070. Mat srcBlack;
  3071. int sucessCs = 0;
  3072. int badCs = 0;
  3073. for (int i = 0; i < cs.Count(); i++)
  3074. {
  3075. srcBlack = new Mat(src.Height, src.Width, MatType.CV_8UC1, new Scalar(0));//黑色底图
  3076. //画圆
  3077. Cv2.Circle(dst, (int)cs[i].Center.X, (int)cs[i].Center.Y, (int)cs[i].Radius, new Scalar(0, 0, 255), 2, LineTypes.AntiAlias);
  3078. //加强圆心显示
  3079. Cv2.Circle(dst, (int)cs[i].Center.X, (int)cs[i].Center.Y, 3, new Scalar(0, 0, 255), 2, LineTypes.AntiAlias);
  3080. //画圆
  3081. Cv2.Circle(srcBlack, (int)cs[i].Center.X, (int)cs[i].Center.Y, (int)cs[i].Radius, Scalar.White, 1, LineTypes.AntiAlias);
  3082. OpenCvSharp.Point[][] contours;
  3083. HierarchyIndex[] hierarchy;
  3084. Cv2.FindContours(srcBlack, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone, null);
  3085. Cv2.DrawContours(srcBlack, contours, -1, Scalar.White, -1, LineTypes.Link8, hierarchy, 4, new OpenCvSharp.Point(0, 0));
  3086. //取所有的点
  3087. List<OpenCvSharp.Point> srPoints = new List<OpenCvSharp.Point>();
  3088. unsafe
  3089. {
  3090. int rows = srcBlack.Height, cols = srcBlack.Width;
  3091. for (int k = 0; k < rows; k++)
  3092. {
  3093. IntPtr a = srcBlack.Ptr(k);
  3094. byte* b = (byte*)a.ToPointer();
  3095. for (int j = 0; j < cols; j++)
  3096. {
  3097. if (b[j] != 0)
  3098. {
  3099. srPoints.Add(new OpenCvSharp.Point(j, k));
  3100. }
  3101. }
  3102. }
  3103. }
  3104. for (int j = 0; j < srPoints.Count; j++)
  3105. {
  3106. int item = src.Get<int>(srPoints[j].Y, srPoints[j].X);
  3107. srcBlack.Set<int>(srPoints[j].Y, srPoints[j].X, item);
  3108. }
  3109. Mat rect = new Mat(srcBlack, Cv2.BoundingRect(contours[0]));
  3110. //Cv2.EqualizeHist(rect, dst);
  3111. Cv2.GaussianBlur(rect, dst, new OpenCvSharp.Size(3, 3), 0);
  3112. //Cv2.MedianBlur(dst, dst, 1);
  3113. Mat aa = dst.Threshold(50, 255, ThresholdTypes.BinaryInv);
  3114. Cv2.FindContours(aa, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone, null);
  3115. Point2f center = new Point2f(aa.Cols / 2, aa.Rows / 2);
  3116. Mat bb = new Mat(aa.Height, aa.Width, MatType.CV_8UC1, new Scalar(0));//黑色底图
  3117. Cv2.Circle(bb, (int)center.X, (int)center.Y, (int)cs[i].Radius - 15, Scalar.White, 1, LineTypes.AntiAlias);
  3118. OpenCvSharp.Point[][] contoursCircleLine;
  3119. HierarchyIndex[] hierarchyLine;
  3120. Cv2.FindContours(bb, out contoursCircleLine, out hierarchyLine, RetrievalModes.External, ContourApproximationModes.ApproxNone, null);
  3121. List<OpenCvSharp.Point> contoursCircleLineOne = new List<OpenCvSharp.Point>();
  3122. for (int m = 0; m < contoursCircleLine.Count(); m++)
  3123. {
  3124. for (int n = 0; n < contoursCircleLine[m].Count(); n++)
  3125. {
  3126. contoursCircleLineOne.Add(contoursCircleLine[m][n]);
  3127. }
  3128. }
  3129. //内缩
  3130. Rect bigRect = new Rect(0, 0, rect.Width, rect.Height);
  3131. for (int nX = bigRect.X; nX <= bigRect.Right; nX++)
  3132. {
  3133. for (int nY = bigRect.Y; nY <= bigRect.Bottom; nY++)
  3134. {
  3135. double localPos = Cv2.PointPolygonTest(contoursCircleLineOne, new Point2f(nX, nY), false);
  3136. if (localPos == 1 || localPos == 0)//像素点在多边形内和边缘
  3137. {
  3138. }
  3139. else
  3140. {
  3141. aa.Set<int>(nX, nY, 0);
  3142. }
  3143. }
  3144. }
  3145. Cv2.FindContours(aa, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone, null);
  3146. Cv2.CvtColor(aa, aa, ColorConversionCodes.RGB2BGR);
  3147. List<OpenCvSharp.Point[]> contoursHoleList = contours.OrderByDescending(t => t.Count()).ToList();
  3148. if (contoursHoleList.Count == 0)
  3149. {
  3150. continue;
  3151. }
  3152. List<int> maxList = new List<int>();
  3153. int MaxListCount = 5;
  3154. if (contoursHoleList.Count < MaxListCount)
  3155. {
  3156. MaxListCount = contoursHoleList.Count;
  3157. }
  3158. for (int g = 0; g < contoursHoleList.Count; g++)
  3159. {
  3160. maxList.Add(contoursHoleList[g].Count());
  3161. if (g == MaxListCount - 1)
  3162. {
  3163. break;
  3164. }
  3165. }
  3166. for (int k = 0; k < contours.Count(); k++)
  3167. {
  3168. RotatedRect rectR = Cv2.MinAreaRect(contours[k]); //计算每个轮廓最小外接矩形
  3169. Rect rectB = Cv2.BoundingRect(contours[k]);
  3170. float width = rectR.Size.Width >= rectR.Size.Height ? rectR.Size.Width : rectR.Size.Height;
  3171. float height = rectR.Size.Width < rectR.Size.Height ? rectR.Size.Width : rectR.Size.Height;
  3172. height = height == 0 ? 1 : height;
  3173. if (maxList.Contains(contours[k].Count()))
  3174. {
  3175. double distance = 0;
  3176. for (int m = 0; m < contours[k].Count(); m++)
  3177. {
  3178. Point2f centerCoutours = new Point2f(contours[k][m].X, contours[k][m].Y);
  3179. distance += centerCoutours.DistanceTo(center);
  3180. }
  3181. distance = distance / contours[k].Count();
  3182. OpenCvSharp.Point[] lineDmax = new OpenCvSharp.Point[2];
  3183. RotatedRect minRect;
  3184. // double ratio = GetDMax(contours[k], out lineDmax) / GetDMin(contours[k], out minRect);
  3185. if (distance > 55)
  3186. {
  3187. Cv2.DrawContours(aa, contours, k, Scalar.Yellow, -1, LineTypes.Link8, hierarchy, 4, new OpenCvSharp.Point(0, 0));
  3188. }
  3189. else if (/*ratio > 2 && */Cv2.ArcLength(contours[k], true) < 15)
  3190. {
  3191. Cv2.DrawContours(aa, contours, k, Scalar.Blue, -1, LineTypes.Link8, hierarchy, 4, new OpenCvSharp.Point(0, 0));
  3192. }
  3193. else
  3194. {
  3195. Cv2.DrawContours(aa, contours, k, Scalar.Green, -1, LineTypes.Link8, hierarchy, 4, new OpenCvSharp.Point(0, 0));
  3196. }
  3197. }
  3198. else
  3199. {
  3200. Cv2.DrawContours(aa, contours, k, Scalar.Red, -1, LineTypes.Link8, hierarchy, 4, new OpenCvSharp.Point(0, 0));
  3201. }
  3202. }
  3203. using (new Window("OutputImage", WindowMode.Normal, rect))
  3204. using (new Window("InputImage", WindowMode.Normal, aa))
  3205. {
  3206. //Cv2.WaitKey(0);
  3207. if (MessageBox.Show("当前识别率:" + ((float)sucessCs / (sucessCs + badCs) * 100) + "是否正确?", "识别判断", MessageBoxButtons.YesNo) == DialogResult.Yes)
  3208. {
  3209. sucessCs += 1;
  3210. }
  3211. else
  3212. {
  3213. badCs += 1;
  3214. }
  3215. }
  3216. }
  3217. MessageBox.Show("识别准确率: " + ((float)sucessCs / cs.Count() * 100));
  3218. }
  3219. #endregion
  3220. #endregion
  3221. #region 单晶
  3222. /// <summary>
  3223. /// 筛选单晶
  3224. /// </summary>
  3225. /// <returns></returns>
  3226. public List<List<int>> ForgetCrystal(double pointsize)
  3227. {
  3228. List<List<int>> data = new List<List<int>>() { };
  3229. ProgressThreadProcClass procClass = new ProgressThreadProcClass();
  3230. int itemCount = 100;
  3231. Mat newMat = new Mat();
  3232. Bitmap bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
  3233. ProgressThreadProcClass.IFileTransferProgressEvents progressEvents = new ProgressThreadProcClass.IFileTransferProgressEvents();
  3234. System.Threading.ThreadStart copyThreadProc =
  3235. delegate ()
  3236. {
  3237. try
  3238. {
  3239. action.Lists.Add(new Args() { Key = "SelPointFs", Value = -1 });
  3240. action.Lists.Add(new Args() { Key = "imageTypes", Value = 12 });
  3241. action.Lists.Add(new Args() { Key = "pointsize", Value = pointsize });
  3242. action.Lists.Add(new Args() { Key = "borderBottom", Value = borderBottom });
  3243. action.Lists.Add(new Args() { Key = "border", Value = border });
  3244. action.Lists.Add(new Args() { Key = "HW", Value = HW });
  3245. action.Lists.Add(new Args() { Key = "AreaRatio", Value = AreaRatio });
  3246. action.Lists.Add(new Args() { Key = "isDis", Value = isDis });
  3247. action.Lists.Add(new Args() { Key = "isJu", Value = isJu });
  3248. string subPath = System.Configuration.ConfigurationManager.AppSettings["TempPath"];
  3249. string newbitmap = subPath + "\\mask.jpg";
  3250. Mat mask = Cv2.ImRead(newbitmap);
  3251. newMat = this.PerformProcessGetdata(mask, out data);
  3252. //newMat = this.PerformProcessGetdata(OpenCvSharp.Extensions.BitmapConverter.ToMat(bitDJ), out data);
  3253. }
  3254. catch (Exception e)
  3255. {
  3256. }
  3257. finally
  3258. {
  3259. progressEvents.EndOperation(OperationResult.Finished);
  3260. }
  3261. };
  3262. procClass.StartProgressAction(/*currentForm*/parentSinglCrystal, itemCount, copyThreadProc, progressEvents, null);
  3263. if (bmc != null) { bmc.data = data; bmc.isedit = true; }
  3264. if (bc != null) { bc.data = data; bc.isedit = true; }
  3265. documentWorkspace.PhaseModels[0].mat = newMat;
  3266. documentWorkspace.Refresh();
  3267. return data;
  3268. }
  3269. /// <summary>
  3270. /// 删除添加单晶
  3271. /// </summary>
  3272. /// <returns></returns>
  3273. public List<List<int>> DeleteCrystal(List<PointF> pointFs, List<List<PointF>> addPoints)
  3274. {
  3275. List<List<int>> data = new List<List<int>>() { };
  3276. ProgressThreadProcClass procClass = new ProgressThreadProcClass();
  3277. int itemCount = 100;
  3278. Mat newMat = new Mat();
  3279. Bitmap bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
  3280. ProgressThreadProcClass.IFileTransferProgressEvents progressEvents = new ProgressThreadProcClass.IFileTransferProgressEvents();
  3281. System.Threading.ThreadStart copyThreadProc =
  3282. delegate ()
  3283. {
  3284. try
  3285. {
  3286. List<List<OpenCvSharp.Point>> AddPoints = new List<List<OpenCvSharp.Point>>();
  3287. if (addPoints.Count > 0)
  3288. {
  3289. for (int i = 0; i < addPoints.Count; i++)
  3290. {
  3291. List<OpenCvSharp.Point> plist = new List<OpenCvSharp.Point>();
  3292. addPoints[i].ForEach(p => plist.Add(new OpenCvSharp.Point((int)p.X, (int)p.Y)));
  3293. AddPoints.Add(plist);
  3294. }
  3295. }
  3296. action.Lists.Add(new Args() { Key = "SelPointFs", Value = -1 });
  3297. action.Lists.Add(new Args() { Key = "imageTypes", Value = 12 });
  3298. action.Lists.Add(new Args() { Key = "DelPointFs", Value = pointFs });
  3299. action.Lists.Add(new Args() { Key = "AddPontins", Value = AddPoints });
  3300. string subPath = System.Configuration.ConfigurationManager.AppSettings["TempPath"];
  3301. string newbitmap = subPath + "\\mask.jpg";
  3302. Mat mask = Cv2.ImRead(newbitmap);
  3303. newMat = this.PerformProcessGetdata(mask, out data);
  3304. //newMat = this.PerformProcessGetdata(OpenCvSharp.Extensions.BitmapConverter.ToMat(bitDJ), out data);
  3305. }
  3306. catch (Exception e)
  3307. {
  3308. }
  3309. finally
  3310. {
  3311. progressEvents.EndOperation(OperationResult.Finished);
  3312. }
  3313. };
  3314. procClass.StartProgressAction(/*currentForm*/parentSinglCrystal, itemCount, copyThreadProc, progressEvents, null);
  3315. if (bmc != null) { bmc.data = data; bmc.isedit = true; }
  3316. if (bc != null) { bc.data = data; bc.isedit = true; }
  3317. documentWorkspace.PhaseModels[0].mat = newMat;
  3318. documentWorkspace.Refresh();
  3319. return data;
  3320. }
  3321. /// <summary>
  3322. /// 绘制单晶选择
  3323. /// </summary>
  3324. /// <returns></returns>
  3325. public void DrwCrystalSelected(int select)
  3326. {
  3327. List<List<int>> data = new List<List<int>>() { };
  3328. Bitmap bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
  3329. action.Lists.Add(new Args() { Key = "SelPointFs", Value = select });
  3330. Mat newMat = this.PerformProcessGetdata(OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap), out data);
  3331. documentWorkspace.PhaseModels[0].mat = newMat;
  3332. documentWorkspace.Refresh();
  3333. }
  3334. private Mat getCutback(Bitmap img)
  3335. {
  3336. Mat mat = OpenCvSharp.Extensions.BitmapConverter.ToMat(img);
  3337. Mat g_grayImage = new Mat();
  3338. Mat g_dstImage = new Mat();
  3339. Mat g_bwImage = new Mat();
  3340. Mat dst = new Mat();
  3341. //灰度图
  3342. Cv2.CvtColor(mat, g_grayImage, ColorConversionCodes.BGR2GRAY);
  3343. //图像二值化
  3344. Cv2.Threshold(g_grayImage, g_bwImage, 0, 255, ThresholdTypes.Binary | ThresholdTypes.Otsu);
  3345. Cv2.ImShow("g_bwImage", g_bwImage);
  3346. OpenCvSharp.Point[][] contours = new OpenCvSharp.Point[][] { };
  3347. HierarchyIndex[] hierarchyIndex = new HierarchyIndex[] { };
  3348. //轮廓
  3349. Cv2.FindContours(g_bwImage, out contours, out hierarchyIndex, RetrievalModes.External, ContourApproximationModes.ApproxNone);
  3350. Mat matret = new Mat(mat.Rows, mat.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 0));
  3351. for (int i = 0; i < contours.Length; i++)
  3352. {
  3353. if (Cv2.ContourArea(contours[i]) < 30)
  3354. continue;
  3355. Cv2.DrawContours(matret, contours, i, new Scalar(255, 144, 30, 255), -1);
  3356. }
  3357. Cv2.BitwiseAnd(mat, matret, dst);
  3358. Cv2.ImShow("dst", dst);
  3359. return dst;
  3360. }
  3361. /// <summary>
  3362. /// 单晶颗粒
  3363. /// </summary>
  3364. private void DanJing(Bitmap img)
  3365. {
  3366. Mat g_srcImage = new Mat();
  3367. Mat M = OpenCvSharp.Extensions.BitmapConverter.ToMat(img);
  3368. Cv2.CvtColor(M, g_srcImage, ColorConversionCodes.BGRA2BGR);
  3369. //调试方便
  3370. // Cv2.Resize(g_srcImage, g_srcImage, new OpenCvSharp.Size(g_srcImage.Cols / 3, g_srcImage.Rows / 3), (0.0), (0.0), OpenCvSharp.InterpolationFlags.Area);
  3371. int rows = g_srcImage.Rows;
  3372. int cols = g_srcImage.Cols;
  3373. g_srcImage = g_srcImage[new Rect(0, 0, cols, rows - 50)];
  3374. Mat gray = new Mat(), binary = new Mat(), shifted;
  3375. Cv2.CvtColor(g_srcImage, gray, ColorConversionCodes.BGR2GRAY);
  3376. Mat element = Cv2.GetStructuringElement(MorphShapes.Ellipse, new OpenCvSharp.Size(5, 5), new OpenCvSharp.Point(2, 2));
  3377. Cv2.MorphologyEx(gray, gray, MorphTypes.Open, element);//
  3378. Cv2.Threshold(gray, binary, 0, 255, ThresholdTypes.Binary | ThresholdTypes.Otsu);
  3379. Cv2.ImShow("二值图像", binary);
  3380. Mat labels = new Mat();
  3381. int n_comps = Cv2.ConnectedComponents(binary, labels, PixelConnectivity.Connectivity4);
  3382. Dictionary<int, List<OpenCvSharp.Point>> particlePixles = new Dictionary<int, List<OpenCvSharp.Point>>();
  3383. //draw
  3384. rows = g_srcImage.Rows;
  3385. cols = g_srcImage.Cols;
  3386. Mat src_color = new Mat();// = Mat::zeros(imageShold.size(), CV_8UC3);
  3387. src_color.Create(rows, cols, MatType.CV_8UC3);
  3388. // src_color = Scalar.All(0);
  3389. for (int x = 0; x < rows; x++)
  3390. {
  3391. for (int y = 0; y < cols; y++)
  3392. {
  3393. int label = labels.At<int>(x, y);//注意labels是CV_16U类型
  3394. if (label != 0)
  3395. {
  3396. if (particlePixles.ContainsKey(label))
  3397. {
  3398. particlePixles[label].Add(new OpenCvSharp.Point(y, x));
  3399. }
  3400. else
  3401. {
  3402. List<OpenCvSharp.Point> Pixles = new List<OpenCvSharp.Point>();
  3403. Pixles.Add(new OpenCvSharp.Point(y, x));
  3404. particlePixles.Add(label, Pixles);
  3405. }
  3406. }
  3407. if (label == 0)
  3408. {
  3409. src_color.Set<Vec3b>(x, y, new Vec3b(255, 255, 255));
  3410. continue;
  3411. }
  3412. Vec3b vec3 = new Vec3b((byte)((label * 10 * 10 * 10) % 255), (byte)((label * 10 * 10) % 255), (byte)((label * 10) % 255));
  3413. src_color.Set<Vec3b>(x, y, vec3);
  3414. }
  3415. }
  3416. int partnum = 0;
  3417. int image1 = 0;
  3418. foreach (var item in particlePixles)
  3419. {
  3420. List<OpenCvSharp.Point> pixel = item.Value;
  3421. Rect rect = Cv2.BoundingRect(pixel);
  3422. Mat particle = g_srcImage[rect];
  3423. string windowName = string.Format("{0}", image1++) + ".jpg";
  3424. int num = TinyParticle(particle, windowName);
  3425. // Mat outImage =Cv2.ImRead(windowName);
  3426. partnum += num;
  3427. // Cv2.AddWeighted(particle, 0, outImage, 1, 0, particle);
  3428. }
  3429. Cv2.ImShow("原始图像", g_srcImage);
  3430. }
  3431. int GetNumber(int input)
  3432. {
  3433. int number = 0;
  3434. while (input > 0)
  3435. {
  3436. if (input != 0)
  3437. {
  3438. number++;
  3439. }
  3440. input = input / 10;
  3441. }
  3442. return number;
  3443. }
  3444. int TinyParticle(Mat image, string filename)
  3445. {
  3446. //灰度化,滤波,Canny边缘检测
  3447. Mat imageGray = new Mat();
  3448. // Cv2.Resize(image, image, new OpenCvSharp.Size(image.Cols / 10, image.Rows / 3), (0.0), (0.0), OpenCvSharp.InterpolationFlags.Area);
  3449. Cv2.PyrMeanShiftFiltering(image, image, 20, 48); //模糊细节,这个参数由颗粒的大小确定
  3450. Cv2.CvtColor(image, imageGray, ColorConversionCodes.BGR2GRAY);//灰度转换
  3451. //区间滤波
  3452. for (int i = 0; i < imageGray.Rows; i++)
  3453. {
  3454. for (int j = 0; j < imageGray.Cols; j++)
  3455. {
  3456. if (imageGray.At<int>(i, j) > 105 && imageGray.At<int>(i, j) < 130)
  3457. {
  3458. imageGray.Set<int>(i, j, 255);
  3459. }
  3460. else
  3461. {
  3462. imageGray.Set<int>(i, j, 0);
  3463. }
  3464. }
  3465. }
  3466. OpenCvSharp.Point[][] contours = new OpenCvSharp.Point[][] { };
  3467. HierarchyIndex[] hierarchyIndex = new HierarchyIndex[] { };
  3468. //轮廓
  3469. Cv2.FindContours(imageGray, out contours, out hierarchyIndex, RetrievalModes.External, ContourApproximationModes.ApproxNone);
  3470. double maxArea = 0;
  3471. List<double> listArea = new List<double>();
  3472. List<OpenCvSharp.Point[]> paint = new List<OpenCvSharp.Point[]>();
  3473. Random ran = new Random();
  3474. for (int t = 0; t < contours.Length; t++)
  3475. {
  3476. double area = Cv2.ContourArea(contours[t]);
  3477. int p = GetNumber((int)area);
  3478. if (p >= 4)
  3479. {
  3480. int r = ran.Next(0, 255);
  3481. int g = ran.Next(0, 255);
  3482. int b = ran.Next(0, 255);
  3483. Cv2.FillPoly(image, new OpenCvSharp.Point[][] { contours[t] }, new OpenCvSharp.Scalar((byte)b, (byte)g, (byte)r));
  3484. paint.Add(contours[t]);
  3485. }
  3486. listArea.Add(area);
  3487. }
  3488. // Cv2.Resize(image, image, new OpenCvSharp.Size(image.Cols *0.1, image.Rows *0.1), (0.0), (0.0), OpenCvSharp.InterpolationFlags.Area);
  3489. //Cv2.ImShow(filename, image);
  3490. return paint.Count;
  3491. }
  3492. /// <summary>
  3493. /// 分水岭
  3494. /// </summary>
  3495. /// <param name="img"></param>
  3496. /// <returns></returns>
  3497. private Mat GetWatershedSegment(Mat M, out List<List<int>> outdata)
  3498. {
  3499. List<List<OpenCvSharp.Point>> points = new List<List<OpenCvSharp.Point>>();
  3500. particlePixles = new Dictionary<int, List<OpenCvSharp.Point>>();
  3501. relit = new List<int>();
  3502. g_srcImage = new Mat();
  3503. temp = new Mat(); outdata = new List<List<int>>() { };
  3504. Cv2.CvtColor(M, g_srcImage, ColorConversionCodes.BGRA2BGR);
  3505. Mat gray = new Mat();
  3506. Mat binary = new Mat();
  3507. Mat shifted = new Mat(M.Size(), MatType.CV_8UC3);
  3508. //均值漂移 滤波
  3509. // Cv2.PyrMeanShiftFiltering(g_srcImage, shifted, 21, 51);
  3510. Cv2.GaussianBlur(g_srcImage, shifted, new OpenCvSharp.Size(15, 15), 0);
  3511. //灰度图
  3512. Cv2.CvtColor(shifted, gray, ColorConversionCodes.BGR2GRAY);
  3513. //二值化
  3514. double otsu = Cv2.Threshold(gray, binary, 0, 255, ThresholdTypes.Otsu/*.Otsu*/);
  3515. // distance transform
  3516. Mat dist = new Mat();
  3517. Cv2.DistanceTransform(binary, dist, DistanceTypes.L2, DistanceMaskSize.Mask3);
  3518. //归一化数据
  3519. Cv2.Normalize(dist, dist, 0, 1, NormTypes.MinMax);
  3520. // binary
  3521. Cv2.Threshold(dist, dist, 0.4, 1, ThresholdTypes.Binary);
  3522. // markers
  3523. Mat dist_m = new Mat();
  3524. dist.ConvertTo(dist_m, MatType.CV_8UC1);
  3525. OpenCvSharp.Point[][] contours = new OpenCvSharp.Point[][] { };
  3526. HierarchyIndex[] hierarchyIndex = new HierarchyIndex[] { };
  3527. Cv2.FindContours(dist_m, out contours, out hierarchyIndex, RetrievalModes.External, ContourApproximationModes.ApproxNone);
  3528. // create markers
  3529. Mat markers = Mat.Zeros(g_srcImage.Size(), MatType.CV_32SC1);
  3530. for (int t = 0; t < contours.Length; t++)
  3531. {
  3532. if (Cv2.ContourArea(contours[t]) > markers.Rows * markers.Cols * 0.1)
  3533. {
  3534. continue;
  3535. }
  3536. Cv2.DrawContours(markers, contours, t, new Scalar(t + 1), -1);
  3537. }
  3538. // Cv2.ImShow("分割后", markers);
  3539. Cv2.Circle(markers, new OpenCvSharp.Point(5, 5), 30, new Scalar(255), -1);
  3540. //形体学操作 去掉干扰
  3541. InputArray kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(3, 3), new OpenCvSharp.Point(-1, -1));
  3542. Cv2.MorphologyEx(g_srcImage, g_srcImage, MorphTypes.Erode, kernel);
  3543. Cv2.Watershed(g_srcImage, markers);
  3544. // 颜色填充与最终显示
  3545. int index = 0;
  3546. for (int row = 0; row < markers.Rows; row++)
  3547. {
  3548. for (int col = 0; col < markers.Cols; col++)
  3549. {
  3550. index = markers.At<int>(row, col);
  3551. if (index > 0 && index <= contours.Length)
  3552. {
  3553. if (particlePixles.ContainsKey(index))
  3554. {
  3555. particlePixles[index].Add(new OpenCvSharp.Point(col, row));
  3556. }
  3557. else
  3558. {
  3559. List<OpenCvSharp.Point> Pixles = new List<OpenCvSharp.Point>();
  3560. Pixles.Add(new OpenCvSharp.Point(col, row));
  3561. particlePixles.Add(index, Pixles);
  3562. }
  3563. }
  3564. }
  3565. }
  3566. int k = 0;
  3567. foreach (var item in particlePixles)
  3568. {
  3569. if (item.Value.Count > 99999)
  3570. {
  3571. k = item.Key;
  3572. }
  3573. else
  3574. {
  3575. points.Add(item.Value);
  3576. }
  3577. }
  3578. particlePixles.Remove(k);
  3579. //temp = Adjust.BaseImage.BaseTools.MergeMatFromMatArr(temp, vec4B);
  3580. int q = 0;
  3581. int iskailie = 0;
  3582. temp = new Mat(g_srcImage.Rows, g_srcImage.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 0));
  3583. int index1 = 0;
  3584. foreach (var item in particlePixles)
  3585. {
  3586. // 将轮廓转为矩形框 , 这个最大的矩形为感兴趣的图像
  3587. Rect rect = Cv2.BoundingRect(item.Value);
  3588. List<OpenCvSharp.Point> pixel = item.Value;
  3589. Mat particle = g_srcImage[rect];
  3590. int ret = 0;
  3591. double area = Cv2.ContourArea(item.Value);
  3592. int x = rect.X;
  3593. int y = rect.Y;
  3594. int width = rect.Width;
  3595. int height = rect.Height;
  3596. List<int> po = new List<int>() { x, y, width, height, (int)area, item.Key };
  3597. outdata.Add(po);
  3598. index1++;
  3599. }
  3600. Cv2.DrawContours(temp, points, -1, new Scalar(255, 0, 0, 255), -1);
  3601. //Mat temp1 = new Mat();
  3602. //Cv2.Erode(temp, temp1, null);
  3603. //temp = temp - temp1;
  3604. using (new Window("temp", WindowMode.Normal, temp))
  3605. {
  3606. Cv2.WaitKey(0);
  3607. }
  3608. return temp;
  3609. Mat after = new Mat();
  3610. Cv2.ConvertScaleAbs(markers, after);
  3611. using (new Window("", WindowMode.Normal, after))
  3612. {
  3613. Cv2.WaitKey(0);
  3614. }
  3615. return after;
  3616. }
  3617. #endregion
  3618. #region 二次球与单晶
  3619. /// <summary>
  3620. /// 获取开裂球
  3621. /// </summary>
  3622. /// <param name="img"></param>
  3623. /// <returns></returns>
  3624. private Mat GetBallAndCrya(Bitmap img, out List<List<int>> outdata)
  3625. {
  3626. particlePixles = new Dictionary<int, List<OpenCvSharp.Point>>();
  3627. relit = new List<int>();
  3628. g_srcImage = new Mat();
  3629. temp = new Mat();
  3630. outdata = new List<List<int>>() { };
  3631. Mat M = OpenCvSharp.Extensions.BitmapConverter.ToMat(img);
  3632. //M.ConvertTo(g_srcImage, MatType.CV_8UC3);
  3633. Cv2.CvtColor(M, g_srcImage, ColorConversionCodes.BGRA2BGR);
  3634. if (lineList_ball.Count > 0)
  3635. {
  3636. for (int line = 0; line < lineList_ball.Count; line++)
  3637. {
  3638. List<PointF> pointList = lineList_ball[line];
  3639. for (int i = 0; i < pointList.Count - 1; i++)
  3640. {
  3641. Cv2.Line(g_srcImage, new OpenCvSharp.Point() { X = (int)pointList[i].X, Y = (int)pointList[i].Y }, new OpenCvSharp.Point() { X = (int)pointList[i + 1].X, Y = (int)pointList[i + 1].Y }, new Scalar(0, 0, 0), 5);
  3642. }
  3643. }
  3644. }
  3645. //调试方便
  3646. // Cv2.Resize(g_srcImage, g_srcImage,new OpenCvSharp.Size(g_srcImage.Cols / 3, g_srcImage.Rows / 3), (0.0), (0.0), OpenCvSharp.InterpolationFlags.Area);
  3647. Mat gray = new Mat();
  3648. Mat binary = new Mat();
  3649. Mat shifted = new Mat(M.Size(), MatType.CV_8UC3);
  3650. //均值漂移 滤波
  3651. // Cv2.PyrMeanShiftFiltering(g_srcImage, shifted, 21, 51);
  3652. Cv2.GaussianBlur(g_srcImage, shifted, new OpenCvSharp.Size(15, 15), 0);
  3653. //灰度图
  3654. Cv2.CvtColor(shifted, gray, ColorConversionCodes.BGR2GRAY);
  3655. //二值化
  3656. double otsu = Cv2.Threshold(gray, binary, 0, 255, ThresholdTypes.Otsu/*.Otsu*/);
  3657. // distance transform
  3658. Mat dist = new Mat();
  3659. Cv2.DistanceTransform(binary, dist, DistanceTypes.L2, DistanceMaskSize.Mask3);
  3660. //归一化数据
  3661. Cv2.Normalize(dist, dist, 0, 1, NormTypes.MinMax);
  3662. // binary
  3663. Cv2.Threshold(dist, dist, 0.4, 1, ThresholdTypes.Binary);
  3664. // markers
  3665. Mat dist_m = new Mat();
  3666. dist.ConvertTo(dist_m, MatType.CV_8UC1);
  3667. OpenCvSharp.Point[][] contours = new OpenCvSharp.Point[][] { };
  3668. HierarchyIndex[] hierarchyIndex = new HierarchyIndex[] { };
  3669. Cv2.FindContours(dist_m, out contours, out hierarchyIndex, RetrievalModes.External, ContourApproximationModes.ApproxNone);
  3670. // create markers
  3671. Mat markers = Mat.Zeros(g_srcImage.Size(), MatType.CV_32SC1);
  3672. for (int t = 0; t < contours.Length; t++)
  3673. {
  3674. Cv2.DrawContours(markers, contours, t, new Scalar(t + 1), -1);
  3675. }
  3676. // Cv2.ImShow("分割后", markers);
  3677. Cv2.Circle(markers, new OpenCvSharp.Point(5, 5), 30, new Scalar(255), -1);
  3678. //形体学操作 去掉干扰
  3679. InputArray kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(3, 3), new OpenCvSharp.Point(-1, -1));
  3680. Cv2.MorphologyEx(g_srcImage, g_srcImage, MorphTypes.Erode, kernel);
  3681. Cv2.Watershed(g_srcImage, markers);
  3682. // 颜色填充与最终显示
  3683. int index = 0;
  3684. for (int row = 0; row < markers.Rows; row++)
  3685. {
  3686. for (int col = 0; col < markers.Cols; col++)
  3687. {
  3688. index = markers.At<int>(row, col);
  3689. if (index > 0 && index <= contours.Length)
  3690. {
  3691. if (particlePixles.ContainsKey(index))
  3692. {
  3693. particlePixles[index].Add(new OpenCvSharp.Point(col, row));
  3694. }
  3695. else
  3696. {
  3697. List<OpenCvSharp.Point> Pixles = new List<OpenCvSharp.Point>();
  3698. Pixles.Add(new OpenCvSharp.Point(col, row));
  3699. particlePixles.Add(index, Pixles);
  3700. }
  3701. }
  3702. }
  3703. }
  3704. int k = 0;
  3705. foreach (var item in particlePixles)
  3706. {
  3707. if (item.Value.Count > 99999)
  3708. {
  3709. k = item.Key;
  3710. break;
  3711. }
  3712. }
  3713. particlePixles.Remove(k);
  3714. //temp = Adjust.BaseImage.BaseTools.MergeMatFromMatArr(temp, vec4B);
  3715. int q = 0;
  3716. int iskailie = 0;
  3717. temp = new Mat(g_srcImage.Rows, g_srcImage.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 0));
  3718. int index1 = 0;
  3719. foreach (var item in particlePixles)
  3720. {
  3721. // 将轮廓转为矩形框 , 这个最大的矩形为感兴趣的图像
  3722. Rect rect = Cv2.BoundingRect(item.Value);
  3723. List<OpenCvSharp.Point> pixel = item.Value;
  3724. Mat particle = g_srcImage[rect];
  3725. Mat back = particle.Clone();
  3726. Mat forwrit = M[rect];
  3727. Mat small = forwrit.Clone();
  3728. long aveg = 0;
  3729. long aveb = 0;
  3730. long aver = 0;
  3731. foreach (var pt in pixel)
  3732. {
  3733. if (kailie_ball.Count > 0)
  3734. {
  3735. PointF p = new PointF() { X = pt.X, Y = pt.Y };
  3736. if (kailie_ball.Contains(p))
  3737. {
  3738. iskailie = 1;
  3739. break;
  3740. }
  3741. }
  3742. if (putong_ball.Count > 0)
  3743. {
  3744. PointF p = new PointF() { X = pt.X, Y = pt.Y };
  3745. if (putong_ball.Contains(p))
  3746. {
  3747. iskailie = 2;
  3748. break;
  3749. }
  3750. }
  3751. aveg += particle.At<Vec3b>(pt.Y - rect.Y, pt.X - rect.X)[0];
  3752. aveb += particle.At<Vec3b>(pt.Y - rect.Y, pt.X - rect.X)[1];
  3753. aver += particle.At<Vec3b>(pt.Y - rect.Y, pt.X - rect.X)[2];
  3754. }
  3755. int ret = 0;
  3756. if (iskailie == 1)
  3757. {
  3758. ret = 1;
  3759. }
  3760. else if (iskailie == 2)
  3761. {
  3762. ret = 0;
  3763. }
  3764. else
  3765. {
  3766. aveg = aveg / pixel.Count;
  3767. aveb = aveb / pixel.Count;
  3768. aver = aver / pixel.Count;
  3769. for (int i = 0; i < back.Cols; i++)
  3770. {
  3771. for (int j = 0; j < back.Rows; j++)
  3772. {
  3773. back.Set<Vec3b>(j, i, new Vec3b((byte)aveg, (byte)aveb, (byte)aver));
  3774. }
  3775. }
  3776. foreach (var pt in pixel)
  3777. {
  3778. back.Set<Vec3b>(pt.Y - rect.Y, pt.X - rect.X, particle.At<Vec3b>(pt.Y - rect.Y, pt.X - rect.X));
  3779. }
  3780. // ret = GetSplit2(back);
  3781. relit.Add(ret);
  3782. }
  3783. if (ret == 1)
  3784. {
  3785. Cv2.DrawContours(temp, new List<List<OpenCvSharp.Point>>() { item.Value }, 0, new Scalar(0, 0, 255, 255), 2);
  3786. }
  3787. else if (ret == 0)
  3788. {
  3789. Cv2.DrawContours(temp, new List<List<OpenCvSharp.Point>>() { item.Value }, 0, new Scalar(255, 0, 0, 255), 2);
  3790. }
  3791. double area = Cv2.ContourArea(item.Value);
  3792. int x = rect.X;
  3793. int y = rect.Y;
  3794. int width = rect.Width;
  3795. int height = rect.Height;
  3796. if (kailie_ball.Count > 0)
  3797. {
  3798. for (int i = 0; i < kailie_ball.Count; i++)
  3799. {
  3800. double px = kailie_ball[i].X;
  3801. double py = kailie_ball[i].Y;
  3802. if (px > x && px < (x + width) && py > y && py < (y + height))
  3803. {
  3804. ret = 1;
  3805. relit[index1] = 1;
  3806. break;
  3807. }
  3808. }
  3809. }
  3810. if (putong_ball.Count > 0)
  3811. {
  3812. for (int i = 0; i < putong_ball.Count; i++)
  3813. {
  3814. double px = putong_ball[i].X;
  3815. double py = putong_ball[i].Y;
  3816. if (px > x && px < (x + width) && py > y && py < (y + height))
  3817. {
  3818. ret = 0;
  3819. relit[index1] = 0;
  3820. break;
  3821. }
  3822. }
  3823. }
  3824. List<int> po = new List<int>() { x, y, width, height, (int)area, ret };
  3825. outdata.Add(po);
  3826. index1++;
  3827. }
  3828. Mat temp1 = new Mat();
  3829. Cv2.Erode(temp, temp1, null);
  3830. Cv2.Erode(temp1, temp1, null);
  3831. temp = temp - temp1;
  3832. return temp;
  3833. }
  3834. public void test2(string path)
  3835. {
  3836. using (Mat src = new Mat(path, ImreadModes.AnyColor | ImreadModes.AnyDepth))
  3837. using (Mat dst = new Mat())
  3838. {
  3839. //1:因为霍夫圆检测对噪声比较敏感,所以首先对图像做一个中值滤波或高斯滤波(噪声如果没有可以不做)
  3840. Mat m1 = new Mat();
  3841. Cv2.MedianBlur(src, m1, 3); // ksize必须大于1且是奇数
  3842. //2:转为灰度图像
  3843. Mat m2 = m1.Clone();
  3844. //Cv2.CvtColor(m1, m2, ColorConversionCodes.BGR2GRAY);
  3845. //3:霍夫圆检测:使用霍夫变换查找灰度图像中的圆。
  3846. /*
  3847. * 参数:
  3848. * 1:输入参数: 8位、单通道、灰度输入图像
  3849. * 2:实现方法:目前,唯一的实现方法是HoughCirclesMethod.Gradient
  3850. * 3: dp :累加器分辨率与图像分辨率的反比。默认=1
  3851. * 4:minDist: 检测到的圆的中心之间的最小距离。(最短距离-可以分辨是两个圆的,否则认为是同心圆- src_gray.rows/8)
  3852. * 5:param1: 第一个方法特定的参数。[默认值是100] canny边缘检测阈值低
  3853. * 6:param2: 第二个方法特定于参数。[默认值是100] 中心点累加器阈值 – 候选圆心
  3854. * 7:minRadius: 最小半径
  3855. * 8:maxRadius: 最大半径
  3856. *
  3857. */
  3858. //CircleSegment[] cs = Cv2.HoughCircles(m2, HoughMethods.Gradient, 1, 130, 70, 30, 35, 75);
  3859. //CircleSegment[] cs = Cv2.HoughCircles(m2, HoughMethods.Gradient, 1, int.Parse(textBox14.Text), int.Parse(textBox10.Text), int.Parse(textBox11.Text), int.Parse(textBox12.Text), int.Parse(textBox13.Text));
  3860. CircleSegment[] cs = Cv2.HoughCircles(m2, HoughMethods.Gradient, 1, 80, 70, 30, 30, 50);
  3861. src.CopyTo(dst);
  3862. //大圆
  3863. for (int i = 0; i < cs.Count(); i++)
  3864. {
  3865. //画圆
  3866. Cv2.Circle(dst, (int)cs[i].Center.X, (int)cs[i].Center.Y, (int)cs[i].Radius + 10, new Scalar(0, 0, 255), -1, LineTypes.AntiAlias);
  3867. //加强圆心显示
  3868. Cv2.Circle(dst, (int)cs[i].Center.X, (int)cs[i].Center.Y, 3, new Scalar(0, 0, 255), 2, LineTypes.AntiAlias);
  3869. }
  3870. using (new Window("OutputImage", WindowMode.Normal, src))
  3871. //using (new Window("InputImage", WindowMode.Normal, src))
  3872. {
  3873. Cv2.WaitKey(0);
  3874. }
  3875. Mat oldDst = dst.Clone();
  3876. OpenCvSharp.Point[][] contours = new OpenCvSharp.Point[][] { };
  3877. HierarchyIndex[] hierarchy;
  3878. Cv2.GaussianBlur(dst, dst, new OpenCvSharp.Size(25, 25), 0, 0, BorderTypes.Default);
  3879. Cv2.Threshold(dst, dst, 140, 255, ThresholdTypes.Binary);
  3880. using (new Window("InputImage", WindowMode.Normal, dst))
  3881. {
  3882. Cv2.WaitKey(0);
  3883. }
  3884. Cv2.FindContours(dst, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone, null);
  3885. Cv2.CvtColor(oldDst, oldDst, ColorConversionCodes.RGB2BGR);
  3886. Cv2.DrawContours(oldDst, contours, -1, Scalar.Green, -1, LineTypes.Link8, hierarchy, 4, new OpenCvSharp.Point(0, 0));
  3887. using (new Window("InputImage", WindowMode.Normal, oldDst))
  3888. {
  3889. Cv2.WaitKey(0);
  3890. }
  3891. }
  3892. }
  3893. #endregion
  3894. #region 二次球粒径
  3895. /// <summary>
  3896. /// 筛选单晶
  3897. /// </summary>
  3898. /// <returns></returns>
  3899. public List<List<int>> ForgetPrimary(double pointsize)
  3900. {
  3901. List<List<int>> data = new List<List<int>>() { };
  3902. ProgressThreadProcClass procClass = new ProgressThreadProcClass();
  3903. int itemCount = 100;
  3904. Mat newMat = new Mat();
  3905. Bitmap bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
  3906. ProgressThreadProcClass.IFileTransferProgressEvents progressEvents = new ProgressThreadProcClass.IFileTransferProgressEvents();
  3907. System.Threading.ThreadStart copyThreadProc =
  3908. delegate ()
  3909. {
  3910. try
  3911. {
  3912. action.Lists.Add(new Args() { Key = "SelPointFs", Value = -1 });
  3913. action.Lists.Add(new Args() { Key = "imageTypes", Value = 12 });
  3914. action.Lists.Add(new Args() { Key = "pointsize", Value = pointsize });
  3915. action.Lists.Add(new Args() { Key = "border", Value = border });
  3916. action.Lists.Add(new Args() { Key = "HW", Value = HW });
  3917. action.Lists.Add(new Args() { Key = "AreaRatio", Value = AreaRatio });
  3918. action.Lists.Add(new Args() { Key = "Contour", Value = Contour });
  3919. string subPath = System.Configuration.ConfigurationManager.AppSettings["TempPath"];
  3920. string newbitmap = subPath + "\\mask.jpg";
  3921. Mat mask = Cv2.ImRead(newbitmap);
  3922. newMat = this.PerformProcessGetdata(mask, out data);
  3923. //newMat = this.PerformProcessGetdata(OpenCvSharp.Extensions.BitmapConverter.ToMat(bitDJ), out data);
  3924. }
  3925. catch (Exception e)
  3926. {
  3927. }
  3928. finally
  3929. {
  3930. progressEvents.EndOperation(OperationResult.Finished);
  3931. }
  3932. };
  3933. procClass.StartProgressAction(parentPrimary, itemCount, copyThreadProc, progressEvents, null);
  3934. if (bmc != null) { bmc.data = data; bmc.isedit = true; }
  3935. if (bc != null) { bc.data = data; bc.isedit = true; }
  3936. documentWorkspace.PhaseModels[0].mat = newMat;
  3937. documentWorkspace.Refresh();
  3938. return data;
  3939. }
  3940. /// <summary>
  3941. /// 删除添加单晶
  3942. /// </summary>
  3943. /// <returns></returns>
  3944. public List<List<int>> DeletePrimary(List<PointF> pointFs, List<List<PointF>> addPoints)
  3945. {
  3946. List<List<int>> data = new List<List<int>>() { };
  3947. ProgressThreadProcClass procClass = new ProgressThreadProcClass();
  3948. int itemCount = 100;
  3949. Mat newMat = new Mat();
  3950. Bitmap bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
  3951. ProgressThreadProcClass.IFileTransferProgressEvents progressEvents = new ProgressThreadProcClass.IFileTransferProgressEvents();
  3952. System.Threading.ThreadStart copyThreadProc =
  3953. delegate ()
  3954. {
  3955. try
  3956. {
  3957. List<List<OpenCvSharp.Point>> AddPoints = new List<List<OpenCvSharp.Point>>();
  3958. if (addPoints.Count > 0)
  3959. {
  3960. for (int i = 0; i < addPoints.Count; i++)
  3961. {
  3962. List<OpenCvSharp.Point> plist = new List<OpenCvSharp.Point>();
  3963. addPoints[i].ForEach(p => plist.Add(new OpenCvSharp.Point((int)p.X, (int)p.Y)));
  3964. AddPoints.Add(plist);
  3965. }
  3966. }
  3967. action.Lists.Add(new Args() { Key = "SelPointFs", Value = -1 });
  3968. action.Lists.Add(new Args() { Key = "imageTypes", Value = 12 });
  3969. action.Lists.Add(new Args() { Key = "DelPointFs", Value = pointFs });
  3970. action.Lists.Add(new Args() { Key = "AddPontins", Value = AddPoints });
  3971. string subPath = System.Configuration.ConfigurationManager.AppSettings["TempPath"];
  3972. string newbitmap = subPath + "\\mask.jpg";
  3973. Mat mask = Cv2.ImRead(newbitmap);
  3974. newMat = this.PerformProcessGetdata(mask, out data);
  3975. //newMat = this.PerformProcessGetdata(OpenCvSharp.Extensions.BitmapConverter.ToMat(bitDJ), out data);
  3976. }
  3977. catch (Exception e)
  3978. {
  3979. }
  3980. finally
  3981. {
  3982. progressEvents.EndOperation(OperationResult.Finished);
  3983. }
  3984. };
  3985. procClass.StartProgressAction(parentPrimary, itemCount, copyThreadProc, progressEvents, null);
  3986. if (bmc != null) { bmc.data = data; bmc.isedit = true; }
  3987. if (bc != null) { bc.data = data; bc.isedit = true; }
  3988. documentWorkspace.PhaseModels[0].mat = newMat;
  3989. documentWorkspace.Refresh();
  3990. return data;
  3991. }
  3992. #endregion
  3993. #region 标尺自动识别
  3994. /// <summary>
  3995. /// 导出图片
  3996. /// </summary>
  3997. /// <returns></returns>
  3998. public Mat MargMat()
  3999. {
  4000. Bitmap bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
  4001. Mat mat = OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap);
  4002. Mat mat1 = documentWorkspace.phaseModels[0].mat;
  4003. Mat dst = new Mat();
  4004. dst = mat.Clone();
  4005. Mat[] mats = mat1.Split();
  4006. Mat[] arr = mat.Split();
  4007. List<Vec4b> vec4BList = new List<Vec4b>() { new Vec4b(255, 144, 30, 255), new Vec4b(255, 0, 0, 255), new Vec4b(0, 0, 255, 255), new Vec4b(0, 255, 0, 255), new Vec4b(0, 0, 139, 255), new Vec4b(128, 0, 128, 255), new Vec4b(255, 160, 122, 255) };
  4008. List<Vec4b> newlist = new List<Vec4b>();
  4009. Vec4b vec4 = new Vec4b(0, 0, 0, 0);
  4010. for (int i = 0; i < mat1.Cols; i++)
  4011. {
  4012. for (int j = 0; j < mat1.Rows; j++)
  4013. {
  4014. if (mat1.At<Vec4b>(j, i) != vec4)
  4015. {
  4016. dst.Set<Vec4b>(j, i, mat1.At<Vec4b>(j, i));
  4017. }
  4018. else
  4019. {
  4020. dst.Set<Vec4b>(j, i, mat.At<Vec4b>(j, i));
  4021. }
  4022. }
  4023. }
  4024. return dst;
  4025. }
  4026. public static byte[] Bitmap2Byte(Bitmap bitmap)
  4027. {
  4028. using (MemoryStream stream = new MemoryStream())
  4029. {
  4030. bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
  4031. byte[] data = new byte[stream.Length];
  4032. stream.Seek(0, SeekOrigin.Begin);
  4033. stream.Read(data, 0, Convert.ToInt32(stream.Length));
  4034. return data;
  4035. }
  4036. }
  4037. /// <summary>
  4038. /// 根据图片获取标尺
  4039. /// </summary>
  4040. /// <returns></returns>
  4041. public double GetRuler()
  4042. {
  4043. Bitmap bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
  4044. Mat mat = OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap);
  4045. Mat m = Mat.FromImageData(Bitmap2Byte(bitmap));
  4046. Mat gray = mat.CvtColor(ColorConversionCodes.BGRA2GRAY);
  4047. Mat dst = new Mat();
  4048. Cv2.Threshold(gray, dst, 75, 255, ThresholdTypes.BinaryInv);
  4049. OpenCvSharp.Point[][] contours;
  4050. HierarchyIndex[] hierarchy;
  4051. Cv2.FindContours(dst, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone, null);
  4052. List<OpenCvSharp.Point[]> contoursHoleList = contours.OrderByDescending(t => t.Count()).ToList();
  4053. Rect rect = Cv2.BoundingRect(contoursHoleList[1]);
  4054. Rect rect2 = new Rect(new OpenCvSharp.Point(897, 1026), new OpenCvSharp.Size(639, 31));
  4055. //进行裁剪
  4056. Mat imgRect1 = new Mat(dst, rect2);
  4057. Cv2.Threshold(imgRect1, imgRect1, 0, 255, ThresholdTypes.BinaryInv);
  4058. Mat element = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(1, 1));
  4059. Cv2.MorphologyEx(imgRect1, imgRect1, MorphTypes.Close, element);
  4060. int minx = imgRect1.Cols;
  4061. int maxx = 0;
  4062. for (int i = 0; i < imgRect1.Cols; i++)
  4063. {
  4064. int ab = imgRect1.At<int>(3, i);
  4065. if (ab > 0 && i < minx)
  4066. {
  4067. minx = i;
  4068. }
  4069. if (ab > 0 && i > maxx)
  4070. {
  4071. maxx = i;
  4072. }
  4073. }
  4074. int sum = 0;
  4075. for (int i = 0; i < imgRect1.Rows; i++)
  4076. {
  4077. int ab = imgRect1.At<int>(i, maxx);
  4078. if (ab == 0)
  4079. {
  4080. sum++;
  4081. }
  4082. }
  4083. int star = (maxx - minx) / 2 + minx;
  4084. //Rect rect1 = new Rect(star, sum + 3, (maxx - minx) / 2, imgRect1.Rows - sum - 3);
  4085. Cv2.FindContours(imgRect1, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone, null);
  4086. if (contours.Count() > 4)
  4087. {
  4088. contoursHoleList = contours.OrderBy(t => t[0].X).ToList();
  4089. Rect recta = Cv2.BoundingRect(contoursHoleList[1]);
  4090. Rect rectb = Cv2.BoundingRect(contoursHoleList[contoursHoleList.Count - 3]);
  4091. Rect rect1 = new Rect(recta.X, recta.Y, rectb.X - recta.X, recta.Height);
  4092. Mat temp = imgRect1[rect1];
  4093. Rect rectc = Cv2.BoundingRect(contoursHoleList[contoursHoleList.Count - 3]);
  4094. Rect rectd = Cv2.BoundingRect(contoursHoleList[contoursHoleList.Count - 1]);
  4095. Rect rectUnit = new Rect(rectc.X, rectc.Y, rectd.X - rectc.X, rectc.Height);
  4096. Mat tempUnit = imgRect1[rectUnit];
  4097. double unit = GetUnit(tempUnit);
  4098. double d = GetNumForInt2(temp);
  4099. double pix = maxx - minx;
  4100. double ruler = (d * unit) / pix;
  4101. return ruler;
  4102. }
  4103. else
  4104. {
  4105. return 0;
  4106. }
  4107. }
  4108. /// <summary>
  4109. /// 识别数字
  4110. /// </summary>
  4111. /// <param name="temp">需要对比的图片</param>
  4112. /// <returns></returns>
  4113. private int numRecognizer(Mat temp)
  4114. {
  4115. Cv2.BitwiseNot(temp, temp);
  4116. Mat dst = Cv2.ImRead("number.png");
  4117. Mat gray = dst.CvtColor(ColorConversionCodes.BGR2GRAY);
  4118. //第一步找到小数点将图片切开
  4119. OpenCvSharp.Point[][] contours1;
  4120. HierarchyIndex[] hierarchy1;
  4121. Cv2.FindContours(gray, out contours1, out hierarchy1, RetrievalModes.External, ContourApproximationModes.ApproxNone, null);
  4122. List<OpenCvSharp.Point[]> contoursHoleList = contours1.OrderBy(t => t[0].X).ToList();
  4123. List<Mat> numList = new List<Mat>();
  4124. for (int i = 0; i < contoursHoleList.Count(); i++)
  4125. {
  4126. Rect num = Cv2.BoundingRect(contoursHoleList[i]);
  4127. Mat numMat = gray[num];
  4128. numList.Add(numMat);
  4129. }
  4130. //第一步找到小数点将图片切开
  4131. OpenCvSharp.Point[][] contours;
  4132. HierarchyIndex[] hierarchy;
  4133. Cv2.FindContours(temp, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone, null);
  4134. List<OpenCvSharp.Point[]> contoursHole = contours.OrderBy(t => t.Count()).ToList();
  4135. int max = 0;
  4136. for (int i = 0; i < contoursHole.Count(); i++)
  4137. {
  4138. Rect rect = Cv2.BoundingRect(contoursHole[i]);
  4139. Mat numMat = temp[rect];
  4140. if (contoursHole[i].Count() > 3)
  4141. {
  4142. max = rect.X;
  4143. break;
  4144. }
  4145. }
  4146. Rect cut = new Rect(0, 0, max, temp.Rows);
  4147. temp = temp[cut];
  4148. Cv2.FindContours(temp, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone, null);
  4149. List<OpenCvSharp.Point[]> contoursHoleList1 = contours.OrderByDescending(t => t[0].X).ToList();
  4150. int ret = 0;
  4151. for (int i = 0; i < contoursHoleList1.Count(); i++)
  4152. {
  4153. if (contoursHoleList1[i].Count() > 10)
  4154. {
  4155. Rect num = Cv2.BoundingRect(contoursHoleList1[i]);
  4156. Mat numMat = temp[num];
  4157. Cv2.Resize(numMat, numMat, new OpenCvSharp.Size(numList[0].Width, numList[0].Height));
  4158. Mat resultImage = new Mat();
  4159. Cv2.MatchTemplate(numMat, gray, resultImage, TemplateMatchModes.SqDiffNormed);
  4160. double minValue = 0, maxValue = 0;
  4161. OpenCvSharp.Point pointMin = new OpenCvSharp.Point();
  4162. OpenCvSharp.Point pointMax = new OpenCvSharp.Point();
  4163. Cv2.MinMaxLoc(resultImage, out minValue, out maxValue, out pointMin, out pointMax);
  4164. int x = pointMin.X;
  4165. if (x < 1000 && x > 100)
  4166. {
  4167. int m = Convert.ToInt32(x.ToString().Substring(0, 1));
  4168. ret = ret + m * (int)Math.Pow(10, i);
  4169. }
  4170. }
  4171. }
  4172. return ret;
  4173. }
  4174. /// <summary>
  4175. /// 根据图片获取数据
  4176. /// </summary>
  4177. /// <returns></returns>
  4178. public Dictionary<string, string> GetParameter()
  4179. {
  4180. Dictionary<string, string> KeyValues = new Dictionary<string, string>();
  4181. //标尺单位模板纳米和微米
  4182. Mat nm = Cv2.ImRead("xcw/nm.png");
  4183. Mat graynm = nm.CvtColor(ColorConversionCodes.BGR2GRAY);
  4184. //读取原图
  4185. Bitmap bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
  4186. Mat mat = OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap);
  4187. Mat gray = mat.CvtColor(ColorConversionCodes.BGRA2GRAY);
  4188. Mat dst = new Mat();
  4189. //底下的标签是白色的,二值化找标签
  4190. Cv2.Threshold(gray, dst, 245, 255, ThresholdTypes.Binary);
  4191. OpenCvSharp.Point[][] contours;
  4192. HierarchyIndex[] hierarchy;
  4193. Cv2.FindContours(dst, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone, null);
  4194. //找最大白色轮廓就是标签
  4195. List<OpenCvSharp.Point[]> contoursHoleList = contours.OrderByDescending(t => t[0].Y).ToList();
  4196. Mat imgRect1 = new Mat();
  4197. for (int i = 0; i < contoursHoleList.Count; i++)
  4198. {
  4199. if (contoursHoleList[i].Count() > 1000)
  4200. {
  4201. Rect rect = Cv2.BoundingRect(contoursHoleList[i]);
  4202. imgRect1 = new Mat(gray, rect);
  4203. break;
  4204. }
  4205. }
  4206. Cv2.Threshold(imgRect1, imgRect1, 180, 255, ThresholdTypes.BinaryInv);
  4207. #region 标尺识别
  4208. //前5分之一是标尺
  4209. Rect rect1 = new Rect(0, 0, imgRect1.Cols / 5, imgRect1.Rows);
  4210. //进行裁剪`
  4211. Mat mat1 = new Mat(imgRect1, rect1);
  4212. Cv2.FindContours(mat1, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone, null);
  4213. List<OpenCvSharp.Point[]> mat1List = contours.OrderByDescending(t => t[0].Y).ToList();
  4214. Rect rectBC = Cv2.BoundingRect(mat1List[0]);
  4215. int widthBC = rectBC.Width;
  4216. mat1List.RemoveAt(0);
  4217. mat1List = mat1List.OrderByDescending(t => t[0].X).ToList();
  4218. Rect nmrect1 = Cv2.BoundingRect(mat1List[1]);
  4219. Rect nmrect2 = Cv2.BoundingRect(mat1List[0]);
  4220. Rect nmrect = new Rect(nmrect1.X, nmrect1.Y, nmrect2.X - nmrect1.X + nmrect2.Width, nmrect1.Height);
  4221. //找标尺单位
  4222. Mat nmMat = imgRect1[nmrect];
  4223. Mat resultImage = new Mat();
  4224. Cv2.MatchTemplate(nmMat, graynm, resultImage, TemplateMatchModes.SqDiffNormed);
  4225. double minValue = 0, maxValue = 0;
  4226. OpenCvSharp.Point pointMin = new OpenCvSharp.Point();
  4227. OpenCvSharp.Point pointMax = new OpenCvSharp.Point();
  4228. Cv2.MinMaxLoc(resultImage, out minValue, out maxValue, out pointMin, out pointMax);
  4229. int x = pointMin.X;
  4230. int unio = 0;
  4231. if (x > 100)
  4232. {
  4233. unio = 1000;
  4234. }
  4235. else
  4236. {
  4237. unio = 1;
  4238. }
  4239. nmrect = new Rect(0, 0, nmrect1.X, rectBC.Y);
  4240. mat1 = mat1[nmrect];
  4241. int ret = GetNumForInt(mat1);
  4242. ret = ret * unio;
  4243. KeyValues.Add("rule", ret.ToString());
  4244. #endregion
  4245. #region EHT识别
  4246. //5分之一到5分之2是EHT和WD
  4247. Rect rect2 = new Rect(imgRect1.Cols / 5 + 58, 0, imgRect1.Cols / 5 - 100, imgRect1.Rows / 2);
  4248. //进行裁剪`
  4249. Mat mat2 = new Mat(imgRect1, rect2);
  4250. Cv2.FindContours(mat2, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone, null);
  4251. List<OpenCvSharp.Point[]> contoursHole = contours.OrderByDescending(t => t[0].X).ToList();
  4252. nmrect1 = Cv2.BoundingRect(contoursHole[1]);
  4253. nmrect = new Rect(0, 0, nmrect1.X, mat2.Height);
  4254. mat2 = mat2[nmrect];
  4255. double eht = GetNum(mat2);
  4256. KeyValues.Add("eht", eht.ToString());
  4257. #endregion
  4258. #region WD识别
  4259. //5分之一到5分之2是EHT和WD
  4260. Rect rect3 = new Rect(imgRect1.Cols / 5 + 58, imgRect1.Rows / 2, imgRect1.Cols / 5 - 100, imgRect1.Rows / 2);
  4261. //进行裁剪`
  4262. Mat mat3 = new Mat(imgRect1, rect3);
  4263. Cv2.FindContours(mat3, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone, null);
  4264. contoursHole = contours.OrderByDescending(t => t[0].X).ToList();
  4265. nmrect1 = Cv2.BoundingRect(contoursHole[1]);
  4266. nmrect = new Rect(0, 0, nmrect1.X, mat3.Height);
  4267. mat3 = mat3[nmrect];
  4268. double wd = GetNum(mat3);
  4269. KeyValues.Add("wd", wd.ToString());
  4270. #endregion
  4271. #region Mag识别
  4272. //5分之2到5分之3是Mag
  4273. Rect rect4 = new Rect(imgRect1.Cols * 2 / 5 + 80, imgRect1.Rows / 2, imgRect1.Cols / 5 - 100, imgRect1.Rows / 2);
  4274. //进行裁剪`
  4275. Mat mat4 = imgRect1[rect4];
  4276. Cv2.FindContours(mat4, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone, null);
  4277. contoursHole = contours.OrderByDescending(t => t[0].X).ToList();
  4278. nmrect1 = Cv2.BoundingRect(contoursHole[1]);
  4279. nmrect = new Rect(0, 0, nmrect1.X, mat4.Height);
  4280. mat4 = mat4[nmrect];
  4281. double mag = GetNum(mat4);
  4282. KeyValues.Add("mag", mag.ToString());
  4283. #endregion
  4284. #region 日期时间
  4285. //5分之3到5分之4是时间imgRect1.Rows / 2
  4286. Rect rect5 = new Rect(imgRect1.Cols * 3 / 5 + 99, 0, imgRect1.Cols / 5 - 95, imgRect1.Rows / 2);
  4287. //进行裁剪`
  4288. Mat mat5 = imgRect1[rect5];
  4289. Cv2.FindContours(mat5, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone, null);
  4290. contoursHole = contours.OrderBy(t => t[0].X).ToList();
  4291. nmrect1 = Cv2.BoundingRect(contoursHole[2]);
  4292. nmrect = new Rect(0, 0, nmrect1.X, mat5.Height);
  4293. Mat matDD = mat5[nmrect];
  4294. //using (new Window("mat5", WindowMode.Normal, mat5))
  4295. //{
  4296. // Cv2.WaitKey(0);
  4297. //}
  4298. double dateDD = GetNumForInt(matDD);
  4299. nmrect1 = Cv2.BoundingRect(contoursHole[5]);
  4300. nmrect = new Rect(nmrect1.X, 0, mat5.Width - nmrect1.X, mat5.Height);
  4301. Mat matYY = mat5[nmrect];
  4302. double dateYY = GetNumForInt(matYY);
  4303. int endx = nmrect1.X;
  4304. nmrect1 = Cv2.BoundingRect(contoursHole[2]);
  4305. nmrect = new Rect(nmrect1.X, 0, endx - nmrect1.X, mat5.Height);
  4306. Mat matMM = mat5[nmrect];
  4307. string dateMM = GetMonth(matMM);
  4308. rect5 = new Rect(imgRect1.Cols * 3 / 5 + 103, imgRect1.Rows / 2, imgRect1.Cols / 5 - 95, imgRect1.Rows / 2);
  4309. mat5 = imgRect1[rect5];
  4310. Cv2.FindContours(mat5, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone, null);
  4311. contoursHole = contours.OrderBy(t => t[0].X).ToList();
  4312. nmrect1 = Cv2.BoundingRect(contoursHole[2]);
  4313. nmrect = new Rect(0, 0, nmrect1.X, mat5.Height);
  4314. Mat matHH = mat5[nmrect];
  4315. double dateHH = GetNumForInt(matHH);
  4316. nmrect1 = Cv2.BoundingRect(contoursHole[4]);
  4317. nmrect2 = Cv2.BoundingRect(contoursHole[6]);
  4318. nmrect = new Rect(nmrect1.X, 0, nmrect2.X - nmrect1.X, mat5.Height);
  4319. Mat matmm = mat5[nmrect];
  4320. double datemm = GetNumForInt(matmm);
  4321. nmrect1 = Cv2.BoundingRect(contoursHole[8]);
  4322. nmrect = new Rect(nmrect1.X, 0, mat5.Width - nmrect1.X, mat5.Height);
  4323. Mat matSS = mat5[nmrect];
  4324. double dateSS = GetNumForInt(matSS);
  4325. KeyValues.Add("time", dateYY.ToString() + "-" + dateMM + "-" + dateDD.ToString() + " " + dateHH.ToString() + ":" + datemm.ToString() + ":" + dateSS.ToString());
  4326. //using (new Window("time",WindowMode.Normal, matmm))
  4327. //{
  4328. // Cv2.WaitKey(0);
  4329. //}
  4330. #endregion
  4331. return KeyValues;
  4332. }
  4333. /// <summary>
  4334. /// 金相图片标尺识别
  4335. /// </summary>
  4336. /// <returns></returns>
  4337. public int GetParameter2()
  4338. {
  4339. //标尺单位模板纳米和微米
  4340. Mat nm = Cv2.ImRead("xcw/nm.png");
  4341. Mat graynm = nm.CvtColor(ColorConversionCodes.BGR2GRAY);
  4342. //读取原图
  4343. Bitmap bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
  4344. Mat mat = OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap);
  4345. Mat gray = mat.CvtColor(ColorConversionCodes.BGRA2GRAY);
  4346. Mat dst = new Mat();
  4347. //底下的标签是白色的,二值化找标签
  4348. Cv2.Threshold(gray, dst, 245, 255, ThresholdTypes.Binary);
  4349. OpenCvSharp.Point[][] contours;
  4350. HierarchyIndex[] hierarchy;
  4351. Cv2.FindContours(dst, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone, null);
  4352. //找最大白色轮廓就是标签
  4353. List<OpenCvSharp.Point[]> contoursHoleList = contours.OrderBy(t => t[0].Y).ToList();
  4354. Mat imgRect1 = new Mat();
  4355. for (int i = 0; i < contoursHoleList.Count; i++)
  4356. {
  4357. if (contoursHoleList[i].Count() > 100)
  4358. {
  4359. Rect rect = Cv2.BoundingRect(contoursHoleList[i]);
  4360. imgRect1 = new Mat(gray, rect);
  4361. break;
  4362. }
  4363. }
  4364. using (new Window("imgRect1", WindowMode.Normal, imgRect1))
  4365. {
  4366. Cv2.WaitKey(0);
  4367. }
  4368. Cv2.Threshold(imgRect1, imgRect1, 200, 255, ThresholdTypes.BinaryInv);
  4369. Cv2.FindContours(imgRect1, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone, null);
  4370. List<OpenCvSharp.Point[]> mat1List = contours.Where(t => t.Count() > 20).OrderByDescending(t => t[0].Y).ToList();
  4371. Rect rectBC = Cv2.BoundingRect(mat1List[0]);
  4372. int widthBC = rectBC.Width;
  4373. mat1List.RemoveAt(0);
  4374. mat1List = mat1List.OrderByDescending(t => t[0].X).ToList();
  4375. Rect nmrect1 = Cv2.BoundingRect(mat1List[1]);
  4376. Rect nmrect2 = Cv2.BoundingRect(mat1List[0]);
  4377. Rect nmrect = new Rect(nmrect1.X, nmrect1.Y, nmrect2.X - nmrect1.X + nmrect2.Width, nmrect1.Height);
  4378. //找标尺单位
  4379. Mat nmMat = imgRect1[nmrect];
  4380. Mat resultImage = new Mat();
  4381. Cv2.MatchTemplate(nmMat, graynm, resultImage, TemplateMatchModes.SqDiffNormed);
  4382. double minValue = 0, maxValue = 0;
  4383. OpenCvSharp.Point pointMin = new OpenCvSharp.Point();
  4384. OpenCvSharp.Point pointMax = new OpenCvSharp.Point();
  4385. Cv2.MinMaxLoc(resultImage, out minValue, out maxValue, out pointMin, out pointMax);
  4386. int x = pointMin.X;
  4387. int unio = 0;
  4388. if (x > 100)
  4389. {
  4390. unio = 1000;
  4391. }
  4392. else
  4393. {
  4394. unio = 1;
  4395. }
  4396. nmrect = new Rect(0, 0, nmrect1.X, rectBC.Y);
  4397. imgRect1 = imgRect1[nmrect];
  4398. using (new Window("imgRect1", WindowMode.Normal, imgRect1))
  4399. {
  4400. Cv2.WaitKey(0);
  4401. }
  4402. int ret = GetNumForInt2(imgRect1);
  4403. ret = ret * unio;
  4404. return ret;
  4405. }
  4406. /// <summary>
  4407. /// 识别数字带小数点
  4408. /// </summary>
  4409. /// <param name="temp"></param>
  4410. /// <returns></returns>
  4411. private double GetNum(Mat temp)
  4412. {
  4413. double result = 0;
  4414. Mat nm = Cv2.ImRead("xcw/number.png");
  4415. Mat graynm = nm.CvtColor(ColorConversionCodes.BGR2GRAY);
  4416. OpenCvSharp.Point[][] contours;
  4417. HierarchyIndex[] hierarchy;
  4418. Cv2.FindContours(temp, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone, null);
  4419. List<OpenCvSharp.Point[]> contoursHole = contours.OrderBy(t => t.Count()).ToList();
  4420. //小数点坐标
  4421. int max = 0;
  4422. int maxEnd = 0;
  4423. for (int i = 0; i < contoursHole.Count(); i++)
  4424. {
  4425. Rect rectd = Cv2.BoundingRect(contoursHole[i]);
  4426. Mat numMat = temp[rectd];
  4427. if (contoursHole[i].Count() > 3)
  4428. {
  4429. max = rectd.X;
  4430. maxEnd = max + rectd.Width;
  4431. break;
  4432. }
  4433. }
  4434. Rect rectLeft = new Rect(0, 0, max, temp.Height);
  4435. Mat matLeft = temp[rectLeft];
  4436. Cv2.FindContours(matLeft, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone, null);
  4437. contoursHole = contours.OrderByDescending(t => t[0].X).ToList();
  4438. for (int i = 0; i < contoursHole.Count(); i++)
  4439. {
  4440. Rect num = Cv2.BoundingRect(contoursHole[i]);
  4441. Mat numMat = matLeft[num];
  4442. Mat resultImage = new Mat();
  4443. double minValue = 0, maxValue = 0;
  4444. OpenCvSharp.Point pointMin = new OpenCvSharp.Point();
  4445. OpenCvSharp.Point pointMax = new OpenCvSharp.Point();
  4446. Cv2.Resize(numMat, numMat, new OpenCvSharp.Size(13, 19));
  4447. Cv2.MatchTemplate(numMat, graynm, resultImage, TemplateMatchModes.SqDiffNormed);
  4448. Cv2.MinMaxLoc(resultImage, out minValue, out maxValue, out pointMin, out pointMax);
  4449. int x = pointMin.X;
  4450. if (x < 1000 && x > 100)
  4451. {
  4452. int m = Convert.ToInt32(x.ToString().Substring(0, 1));
  4453. result = result + m * Math.Pow(10, i);
  4454. }
  4455. }
  4456. Rect rectRight = new Rect(maxEnd, 0, temp.Width - maxEnd, temp.Height);
  4457. Mat matRight = temp[rectRight];
  4458. Cv2.FindContours(matRight, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone, null);
  4459. contoursHole = contours.OrderBy(t => t[0].X).ToList();
  4460. double w = 1;
  4461. for (int i = 0; i < contoursHole.Count(); i++)
  4462. {
  4463. Rect num = Cv2.BoundingRect(contoursHole[i]);
  4464. Mat numMat = matRight[num];
  4465. Mat resultImage = new Mat();
  4466. double minValue = 0, maxValue = 0;
  4467. OpenCvSharp.Point pointMin = new OpenCvSharp.Point();
  4468. OpenCvSharp.Point pointMax = new OpenCvSharp.Point();
  4469. Cv2.Resize(numMat, numMat, new OpenCvSharp.Size(13, 19));
  4470. Cv2.MatchTemplate(numMat, graynm, resultImage, TemplateMatchModes.SqDiffNormed);
  4471. Cv2.MinMaxLoc(resultImage, out minValue, out maxValue, out pointMin, out pointMax);
  4472. int x = pointMin.X;
  4473. if (x < 1000 && x > 100)
  4474. {
  4475. double m = Convert.ToDouble(x.ToString().Substring(0, 1));
  4476. result = result + m * Math.Pow(10, (w) * -1);
  4477. }
  4478. w = w + 1;
  4479. }
  4480. return result;
  4481. }
  4482. /// <summary>
  4483. /// 识别数字不带小数点
  4484. /// </summary>
  4485. /// <param name="temp"></param>
  4486. /// <returns></returns>
  4487. private int GetNumForInt(Mat temp)
  4488. {
  4489. int result = 0;
  4490. Mat nm = Cv2.ImRead("xcw/number.png");
  4491. Mat graynm = nm.CvtColor(ColorConversionCodes.BGR2GRAY);
  4492. OpenCvSharp.Point[][] contours;
  4493. HierarchyIndex[] hierarchy;
  4494. Cv2.FindContours(temp, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone, null);
  4495. List<OpenCvSharp.Point[]> contoursHole = contours.OrderByDescending(t => t[0].X).ToList();
  4496. for (int i = 0; i < contoursHole.Count(); i++)
  4497. {
  4498. Rect num = Cv2.BoundingRect(contoursHole[i]);
  4499. Mat numMat = temp[num];
  4500. Mat resultImage = new Mat();
  4501. double minValue = 0, maxValue = 0;
  4502. OpenCvSharp.Point pointMin = new OpenCvSharp.Point();
  4503. OpenCvSharp.Point pointMax = new OpenCvSharp.Point();
  4504. Cv2.Resize(numMat, numMat, new OpenCvSharp.Size(13, 19));
  4505. Cv2.MatchTemplate(numMat, graynm, resultImage, TemplateMatchModes.SqDiffNormed);
  4506. Cv2.MinMaxLoc(resultImage, out minValue, out maxValue, out pointMin, out pointMax);
  4507. int x = pointMin.X;
  4508. if (x < 1000 && x > 100)
  4509. {
  4510. int m = Convert.ToInt32(x.ToString().Substring(0, 1));
  4511. result = result + m * (int)Math.Pow(10, i);
  4512. }
  4513. }
  4514. return result;
  4515. }
  4516. /// <summary>
  4517. /// 识别月份
  4518. /// </summary>
  4519. /// <param name="temp"></param>
  4520. /// <returns></returns>
  4521. private string GetMonth(Mat temp)
  4522. {
  4523. string result = "Jan";
  4524. Mat nm = Cv2.ImRead("xcw/month.png");
  4525. Mat graynm = nm.CvtColor(ColorConversionCodes.BGR2GRAY);
  4526. Mat resultImage = new Mat();
  4527. double minValue = 0, maxValue = 0;
  4528. OpenCvSharp.Point pointMin = new OpenCvSharp.Point();
  4529. OpenCvSharp.Point pointMax = new OpenCvSharp.Point();
  4530. Rect rect = new Rect(1175, 0, graynm.Width - 1175, graynm.Height);
  4531. Mat mat = graynm[rect];
  4532. Cv2.Resize(temp, temp, new OpenCvSharp.Size(temp.Width * 1.5, temp.Height * 1.5));
  4533. Cv2.MatchTemplate(temp, graynm, resultImage, TemplateMatchModes.SqDiffNormed);
  4534. Cv2.MinMaxLoc(resultImage, out minValue, out maxValue, out pointMin, out pointMax);
  4535. string[] month = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
  4536. int x = pointMin.X;
  4537. if (x < 1000 && x > 100)
  4538. {
  4539. int m = Convert.ToInt32(x.ToString().Substring(0, 1));
  4540. result = month[m - 1];
  4541. }
  4542. else if (x > 1000)
  4543. {
  4544. int m = Convert.ToInt32(x.ToString().Substring(0, 2));
  4545. result = month[m - 1];
  4546. }
  4547. return result;
  4548. }
  4549. /// <summary>
  4550. /// 识别数字不带小数点
  4551. /// </summary>
  4552. /// <param name="temp"></param>
  4553. /// <returns></returns>
  4554. private int GetNumForInt2(Mat temp)
  4555. {
  4556. int result = 0;
  4557. Mat nm = Cv2.ImRead("number2.png");
  4558. Mat graynm = nm.CvtColor(ColorConversionCodes.BGR2GRAY);
  4559. Cv2.Threshold(graynm, graynm, 0, 255, ThresholdTypes.Otsu);
  4560. //第一步找到小数点将图片切开
  4561. OpenCvSharp.Point[][] contours1;
  4562. HierarchyIndex[] hierarchy1;
  4563. Cv2.FindContours(graynm, out contours1, out hierarchy1, RetrievalModes.External, ContourApproximationModes.ApproxNone, null);
  4564. List<OpenCvSharp.Point[]> contoursHoleList = contours1.OrderBy(t => t[0].X).ToList();
  4565. List<Mat> numList = new List<Mat>();
  4566. for (int i = 0; i < contoursHoleList.Count(); i++)
  4567. {
  4568. Rect num = Cv2.BoundingRect(contoursHoleList[i]);
  4569. Mat numMat = graynm[num];
  4570. numList.Add(numMat);
  4571. }
  4572. OpenCvSharp.Point[][] contours;
  4573. HierarchyIndex[] hierarchy;
  4574. Cv2.FindContours(temp, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone, null);
  4575. List<OpenCvSharp.Point[]> contoursHole = contours.Where(t => t.Count() > 20).OrderByDescending(t => t[0].X).ToList();
  4576. for (int i = 0; i < contoursHole.Count(); i++)
  4577. {
  4578. Rect num = Cv2.BoundingRect(contoursHole[i]);
  4579. Mat numMat = temp[num];
  4580. Mat resultImage = new Mat();
  4581. double minValue = 0, maxValue = 0;
  4582. OpenCvSharp.Point pointMin = new OpenCvSharp.Point();
  4583. OpenCvSharp.Point pointMax = new OpenCvSharp.Point();
  4584. //Cv2.Resize(numMat, numMat, new OpenCvSharp.Size(numList[9].Width, numList[9].Height));
  4585. //using (new Window("ss", WindowMode.Normal, numMat))
  4586. //{
  4587. // Cv2.WaitKey(0);
  4588. //}
  4589. Cv2.MatchTemplate(numMat, graynm, resultImage, TemplateMatchModes.SqDiffNormed);
  4590. Cv2.MinMaxLoc(resultImage, out minValue, out maxValue, out pointMin, out pointMax);
  4591. int x = pointMin.X;
  4592. if (x < 1000 && x > 100)
  4593. {
  4594. int m = Convert.ToInt32(x.ToString().Substring(0, 1));
  4595. result = result + m * (int)Math.Pow(10, i);
  4596. }
  4597. }
  4598. return result;
  4599. }
  4600. private double GetUnit(Mat temp)
  4601. {
  4602. //using (new Window("ss",WindowMode.Normal, temp))
  4603. //{
  4604. // Cv2.WaitKey(0);
  4605. //}
  4606. //标尺单位模板纳米和微米
  4607. Mat nm = Cv2.ImRead("nm.png");
  4608. Mat graynm = nm.CvtColor(ColorConversionCodes.BGR2GRAY);
  4609. Mat resultImage = new Mat();
  4610. Cv2.MatchTemplate(temp, graynm, resultImage, TemplateMatchModes.SqDiffNormed);
  4611. double minValue = 0, maxValue = 0;
  4612. OpenCvSharp.Point pointMin = new OpenCvSharp.Point();
  4613. OpenCvSharp.Point pointMax = new OpenCvSharp.Point();
  4614. Cv2.MinMaxLoc(resultImage, out minValue, out maxValue, out pointMin, out pointMax);
  4615. int x = pointMin.X;
  4616. double unio = 0;
  4617. if (x > 100)
  4618. {
  4619. unio = 1;
  4620. }
  4621. else
  4622. {
  4623. unio = 0.001;
  4624. }
  4625. return unio;
  4626. }
  4627. #endregion
  4628. }
  4629. }