HoleType.cs 435 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996
  1. using System;
  2. using System.Collections.Generic;
  3. using OpenCvSharp;
  4. using System.Linq;
  5. using System.Windows.Forms;
  6. using SmartCoalApplication.Base.CommTool;
  7. using SmartCoalApplication.Base.AuxiliaryCalcModel;
  8. namespace SmartCoalApplication.Base.AutoMeasure
  9. {
  10. public class HoleType : AutoMeasureAnalysis
  11. {
  12. }
  13. public class DataInfor
  14. {
  15. public DataInfor()
  16. {
  17. drawType = "MeasureVLine";
  18. deleteFlag = 2;
  19. }
  20. public int deleteFlag { set; get; }
  21. public string name { set; get; }
  22. public string drawType { set; get; }
  23. public string ID { set; get; }
  24. public double value { set; get; }
  25. public System.Drawing.Point point1 = new System.Drawing.Point();
  26. public System.Drawing.Point point2 = new System.Drawing.Point();
  27. public string aliasName { set; get; }
  28. public void Set(double v, int x1, int y1, int x2, int y2)
  29. {
  30. value = v;
  31. point1.X = x1;
  32. point1.Y = y1;
  33. point2.X = x2;
  34. point2.Y = y2;
  35. }
  36. }
  37. public class ShuangcengbanYou : AutoMeasureAnalysis
  38. {
  39. public DataInfor shangJicaitong = new DataInfor();
  40. public DataInfor xiaJicaitong = new DataInfor();
  41. public DataInfor shangMiantong_Jicaitong = new DataInfor();
  42. public DataInfor xiaMiantong_Jicaitong = new DataInfor();
  43. public DataInfor shangMiantong = new DataInfor();
  44. public DataInfor xiaMiantong = new DataInfor();
  45. public DataInfor kongtong = new DataInfor();
  46. private void Initialize()
  47. {
  48. dataInfors = new List<DataInfor>();
  49. shangJicaitong.name = "上基材銅";
  50. shangJicaitong.ID = "100143";
  51. shangJicaitong.aliasName = "OXWURH";
  52. xiaJicaitong.name = "下基材銅";
  53. xiaJicaitong.ID = "100144";
  54. xiaJicaitong.aliasName = "ZPXAJW";
  55. shangMiantong.name = "上面銅";
  56. shangMiantong.ID = "100147";
  57. shangMiantong.aliasName = "AFZADE";
  58. xiaMiantong.name = "下面銅";
  59. xiaMiantong.ID = "100148";
  60. xiaMiantong.aliasName = "YATJHW";
  61. shangMiantong_Jicaitong.name = "上面銅+基材銅";
  62. shangMiantong_Jicaitong.ID = "100145";
  63. shangMiantong_Jicaitong.aliasName = "GJUWJL";
  64. xiaMiantong_Jicaitong.name = "下面銅+基材銅";
  65. xiaMiantong_Jicaitong.ID = "100146";
  66. xiaMiantong_Jicaitong.aliasName = "COKHSE";
  67. kongtong.name = "孔銅";
  68. kongtong.drawType = "MeasureHLine";
  69. kongtong.ID = "100149";
  70. kongtong.aliasName = "NIVNMR";
  71. dataInfors.Add(shangJicaitong);
  72. dataInfors.Add(xiaJicaitong);
  73. dataInfors.Add(shangMiantong_Jicaitong);
  74. dataInfors.Add(xiaMiantong_Jicaitong);
  75. dataInfors.Add(shangMiantong);
  76. dataInfors.Add(xiaMiantong);
  77. dataInfors.Add(kongtong);
  78. number = 7;
  79. success = 0;
  80. wrongNumber = number;
  81. }
  82. public override void Compute(Mat image, bool isCropFlag, int X, int Y)
  83. {
  84. Initialize();
  85. Ceju ceju = new Ceju();
  86. //获得蓝色,绿色,红色通道图片
  87. Mat[] bgr = Cv2.Split(image);
  88. Mat imageBlue = bgr[0];
  89. Mat imageGreen = bgr[1];
  90. Mat imageRed = bgr[2];
  91. //获得目标区域图片
  92. Mat imageContour = new Mat();
  93. ceju.GetContour(imageRed, out imageContour);
  94. //上下裁剪
  95. int[] y = new int[2] { 0, 0 };
  96. Mat cropContour = new Mat();
  97. ceju.Crop(imageContour, out y, out cropContour, isCropFlag);
  98. //去亮光
  99. int[] b = new int[4] { 0, 0, 0, 0 };
  100. Mat cropContour2 = new Mat();
  101. int border = 0;
  102. ceju.CropLight(cropContour, out border, out cropContour2, "right");
  103. // 计算数据提取区域
  104. int[] dataArea = new int[2];
  105. ceju.GetDataArea(cropContour2, out dataArea, "right");
  106. int middleMianJicaitong = (dataArea[0] + dataArea[1]) / 2;
  107. int middleMiantong = (middleMianJicaitong + dataArea[1]) / 2;
  108. int middleJicaitong = (dataArea[0] + middleMianJicaitong) / 2;
  109. int upper = y[0];
  110. if (isCropFlag)
  111. {
  112. upper += Y;
  113. border += X;
  114. }
  115. //提取綫條
  116. double ordinateL1 = 0;
  117. ceju.ExtractLines(cropContour2, out ordinateL1, middleMianJicaitong, dataArea[1], 1);
  118. double ordinateL3 = 0;
  119. ceju.ExtractLines(cropContour2, out ordinateL3, dataArea[0], middleMianJicaitong, ordinateL1, -1);
  120. shangMiantong_Jicaitong.Set(ordinateL3 - ordinateL1, middleMianJicaitong + border, (int)ordinateL1 + upper, middleMianJicaitong + border, (int)ordinateL3 + upper);
  121. UpdateSuccessLine();
  122. double ordinateL4 = 0;
  123. ceju.ExtractLines(cropContour2, out ordinateL4, dataArea[0], middleMianJicaitong, ordinateL3, 1);
  124. double ordinateL6 = 0;
  125. ceju.ExtractLines2(cropContour2, out ordinateL6, middleMianJicaitong, dataArea[1], 1);
  126. double ordinateL4Copy = 0;
  127. ceju.ExtractLines2(cropContour2, out ordinateL4Copy, middleMianJicaitong, dataArea[1], ordinateL6, -1);
  128. if (ordinateL4Copy < ordinateL4)
  129. ordinateL4 = ordinateL4Copy;
  130. xiaMiantong_Jicaitong.Set(ordinateL6 - ordinateL4, middleMianJicaitong + border, (int)ordinateL4 + upper, middleMianJicaitong + border, (int)ordinateL6 + upper);
  131. UpdateSuccessLine();
  132. // 提取L2
  133. Mat cropGreen = imageGreen[y[0], y[1], border, imageGreen.Cols - 1];
  134. double ordinateL2 = 0;
  135. if (ordinateL1 + 10 < ordinateL3 - 10 && dataArea[0] < dataArea[1])
  136. {
  137. ceju.InsideLine(cropGreen, (int)ordinateL1 + 10, (int)ordinateL3 - 10, dataArea[0], dataArea[1], out ordinateL2);
  138. shangMiantong.Set(ordinateL2 - ordinateL1, middleMiantong + border, (int)ordinateL1 + upper, middleMiantong + border, (int)ordinateL2 + upper);
  139. shangJicaitong.Set(ordinateL3 - ordinateL2, middleJicaitong + border, (int)ordinateL2 + upper, middleJicaitong + border, (int)ordinateL3 + upper);
  140. UpdateSuccessLine();
  141. UpdateSuccessLine();
  142. }
  143. // 提取L5
  144. double ordinateL5 = 0;
  145. if (ordinateL4 + 10 < ordinateL6 - 10 && dataArea[0] < dataArea[1])
  146. {
  147. ceju.InsideLine(cropGreen, (int)ordinateL4 + 10, (int)ordinateL6 - 10, dataArea[0], dataArea[1], out ordinateL5);
  148. xiaMiantong.Set(ordinateL6 - ordinateL5, middleMiantong + border, (int)ordinateL5 + upper, middleMiantong + border, (int)ordinateL6 + upper);
  149. xiaJicaitong.Set(ordinateL5 - ordinateL4, middleJicaitong + border, (int)ordinateL4 + upper, middleJicaitong + border, (int)ordinateL5 + upper);
  150. UpdateSuccessLine();
  151. UpdateSuccessLine();
  152. }
  153. //提取竪綫
  154. double ordinateV1 = 0;
  155. ceju.ExtractVerticalLinesL2R(cropContour2, out ordinateV1, (int)ordinateL3, (int)ordinateL4);
  156. double ordinateV2 = 0;
  157. ceju.ExtractVerticalLinesL2R(cropContour2, out ordinateV2, (int)ordinateL3, (int)ordinateL4, ordinateV1);
  158. int middle2 = (int)((ordinateL3 + ordinateL4) / 2);
  159. kongtong.Set(ordinateV2 - ordinateV1, (int)ordinateV1 + border, middle2 + upper, (int)ordinateV2 + border, middle2 + upper);
  160. UpdateSuccessLine();
  161. //if (isCropFlag)
  162. // UpdateDataInfor(X, Y);
  163. }
  164. }
  165. public class ShuangcengbanZuo : AutoMeasureAnalysis
  166. {
  167. public DataInfor shangJicaitong = new DataInfor();
  168. public DataInfor xiaJicaitong = new DataInfor();
  169. public DataInfor shangMiantong_Jicaitong = new DataInfor();
  170. public DataInfor xiaMiantong_Jicaitong = new DataInfor();
  171. public DataInfor shangMiantong = new DataInfor();
  172. public DataInfor xiaMiantong = new DataInfor();
  173. public DataInfor kongtong = new DataInfor();
  174. private void Initialize()
  175. {
  176. dataInfors = new List<DataInfor>();
  177. shangJicaitong.name = "上基材銅";
  178. shangJicaitong.ID = "100135";
  179. shangJicaitong.aliasName = "CTBCIP";
  180. xiaJicaitong.name = "下基材銅";
  181. xiaJicaitong.ID = "100136";
  182. xiaJicaitong.aliasName = "DJASEN";
  183. shangMiantong.name = "上面銅";
  184. shangMiantong.ID = "100139";
  185. shangMiantong.aliasName = "MIUUXZ";
  186. xiaMiantong.name = "下面銅";
  187. xiaMiantong.ID = "100140";
  188. xiaMiantong.aliasName = "XAVAPO";
  189. shangMiantong_Jicaitong.name = "上面銅+基材銅";
  190. shangMiantong_Jicaitong.ID = "100137";
  191. shangMiantong_Jicaitong.aliasName = "PMMGUC";
  192. xiaMiantong_Jicaitong.name = "下面銅+基材銅";
  193. xiaMiantong_Jicaitong.ID = "100138";
  194. xiaMiantong_Jicaitong.aliasName = "CUTRFE";
  195. kongtong.name = "孔銅";
  196. kongtong.drawType = "MeasureHLine";
  197. kongtong.ID = "100141";
  198. kongtong.aliasName = "LHCLAP";
  199. dataInfors.Add(shangJicaitong);
  200. dataInfors.Add(xiaJicaitong);
  201. dataInfors.Add(shangMiantong_Jicaitong);
  202. dataInfors.Add(xiaMiantong_Jicaitong);
  203. dataInfors.Add(shangMiantong);
  204. dataInfors.Add(xiaMiantong);
  205. dataInfors.Add(kongtong);
  206. number = 7;
  207. success = 0;
  208. wrongNumber = number;
  209. }
  210. public override void Compute(Mat image, bool isCropFlag, int X, int Y)
  211. {
  212. Initialize();
  213. Ceju ceju = new Ceju();
  214. //获得蓝色,绿色,红色通道图片
  215. Mat[] bgr = Cv2.Split(image);
  216. Mat imageBlue = bgr[0];
  217. Mat imageGreen = bgr[1];
  218. Mat imageRed = bgr[2];
  219. //獲得目標區域
  220. Mat imageContour = new Mat();
  221. ceju.GetContour(imageRed, out imageContour);
  222. //上下裁剪
  223. int[] y = new int[2] { 0, 0 };
  224. Mat cropContour = new Mat();
  225. ceju.Crop(imageContour, out y, out cropContour, isCropFlag);
  226. //去亮光
  227. int[] b = new int[4] { 0, 0, 0, 0 };
  228. Mat cropContour2 = new Mat();
  229. int border = 0;
  230. ceju.CropLight(cropContour, out border, out cropContour2, "left");
  231. // 二、计算数据提取区域
  232. int[] dataArea = new int[2];
  233. ceju.GetDataArea(cropContour2, out dataArea, "left");
  234. int middleMianJicaitong = (dataArea[0] + dataArea[1]) / 2;
  235. int middleMiantong = (middleMianJicaitong + dataArea[1]) / 2;
  236. int middleJicaitong = (dataArea[0] + middleMianJicaitong) / 2;
  237. int upper = y[0];
  238. if (isCropFlag)
  239. {
  240. upper += Y;
  241. border += X;
  242. }
  243. //提取綫條
  244. double ordinateL1 = 0;
  245. ceju.ExtractLines(cropContour2, out ordinateL1, dataArea[0], dataArea[1], 1);
  246. double ordinateL3 = 0;
  247. ceju.ExtractLines(cropContour2, out ordinateL3, dataArea[0], dataArea[1], ordinateL1, -1);
  248. shangMiantong_Jicaitong.Set(ordinateL3 - ordinateL1, middleMianJicaitong + border, (int)ordinateL1 + upper, middleMianJicaitong + border, (int)ordinateL3 + upper);
  249. UpdateSuccessLine();
  250. double ordinateL4 = 0;
  251. ceju.ExtractLines(cropContour2, out ordinateL4, dataArea[0], dataArea[1], ordinateL3, 1);
  252. double ordinateL6 = 0;
  253. ceju.ExtractLines2(cropContour2, out ordinateL6, dataArea[0], dataArea[1], 1);
  254. xiaMiantong_Jicaitong.Set(ordinateL6 - ordinateL4, middleMianJicaitong + border, (int)ordinateL4 + upper, middleMianJicaitong + border, (int)ordinateL6 + upper);
  255. UpdateSuccessLine();
  256. // 提取L2
  257. Mat cropGreen = imageGreen[y[0], y[1], border, imageGreen.Cols - 1];
  258. double ordinateL2 = 0;
  259. if (ordinateL1 + 10 < ordinateL3 - 10 && dataArea[0] < dataArea[1])
  260. {
  261. ceju.InsideLine(cropGreen, (int)ordinateL1 + 10, (int)ordinateL3 - 10, dataArea[0], dataArea[1], out ordinateL2);
  262. shangMiantong.Set(ordinateL2 - ordinateL1, middleMiantong + border, (int)ordinateL1 + upper, middleMiantong + border, (int)ordinateL2 + upper);
  263. shangJicaitong.Set(ordinateL3 - ordinateL2, middleJicaitong + border, (int)ordinateL2 + upper, middleJicaitong + border, (int)ordinateL3 + upper);
  264. UpdateSuccessLine();
  265. UpdateSuccessLine();
  266. }
  267. // 提取L5
  268. double ordinateL5 = 0;
  269. if (ordinateL4 + 10 < ordinateL6 - 10 && dataArea[0] < dataArea[1])
  270. {
  271. ceju.InsideLine(cropGreen, (int)ordinateL4 + 10, (int)ordinateL6 - 10, dataArea[0], dataArea[1], out ordinateL5);
  272. xiaMiantong.Set(ordinateL6 - ordinateL5, middleMiantong + border, (int)ordinateL5 + upper, middleMiantong + border, (int)ordinateL6 + upper);
  273. xiaJicaitong.Set(ordinateL5 - ordinateL4, middleJicaitong + border, (int)ordinateL4 + upper, middleJicaitong + border, (int)ordinateL5 + upper);
  274. UpdateSuccessLine();
  275. UpdateSuccessLine();
  276. }
  277. //提取竪綫
  278. double ordinateV1 = 0;
  279. ceju.ExtractVerticalLinesR2L(cropContour2, out ordinateV1, (int)ordinateL3, (int)ordinateL4);
  280. double ordinateV2 = 0;
  281. ceju.ExtractVerticalLinesR2L(cropContour2, out ordinateV2, (int)ordinateL3, (int)ordinateL4, ordinateV1);
  282. int middle2 = (int)((ordinateL3 + ordinateL4) / 2);
  283. kongtong.Set(Math.Abs(ordinateV2 - ordinateV1), (int)ordinateV1 + border, middle2 + upper, (int)ordinateV2 + border, middle2 + upper );
  284. UpdateSuccessLine();
  285. }
  286. }
  287. public class ShuangcengbanQuan : AutoMeasureAnalysis
  288. {
  289. public DataInfor leftShangJicaitong = new DataInfor();
  290. public DataInfor leftXiaJicaitong = new DataInfor();
  291. public DataInfor leftShangMiantong_Jicaitong = new DataInfor();
  292. public DataInfor leftXiaMiantong_Jicaitong = new DataInfor();
  293. public DataInfor leftShangMiantong = new DataInfor();
  294. public DataInfor leftXiaMiantong = new DataInfor();
  295. public DataInfor leftKongtong = new DataInfor();
  296. public DataInfor leftJiaoneisuo = new DataInfor();
  297. public DataInfor rightShangJicaitong = new DataInfor();
  298. public DataInfor rightXiaJicaitong = new DataInfor();
  299. public DataInfor rightShangMiantong_Jicaitong = new DataInfor();
  300. public DataInfor rightXiaMiantong_Jicaitong = new DataInfor();
  301. public DataInfor rightShangMiantong = new DataInfor();
  302. public DataInfor rightXiaMiantong = new DataInfor();
  303. public DataInfor rightKongtong = new DataInfor();
  304. public DataInfor rightJiaoneisuo = new DataInfor();
  305. public DataInfor shangKongjing = new DataInfor();
  306. public DataInfor xiaKongjing = new DataInfor();
  307. private void Initialize()
  308. {
  309. dataInfors = new List<DataInfor>();
  310. leftShangJicaitong.name = "左側上基材銅";
  311. leftShangJicaitong.ID = "100151";
  312. leftShangJicaitong.aliasName = "NJJSLV";
  313. leftXiaJicaitong.name = "左側下基材銅";
  314. leftXiaJicaitong.ID = "100152";
  315. leftXiaJicaitong.aliasName = "ZMVGAK";
  316. leftShangMiantong_Jicaitong.name = "左側上面銅+基材銅";
  317. leftShangMiantong_Jicaitong.ID = "100153";
  318. leftShangMiantong_Jicaitong.aliasName = "VHUWKJ";
  319. leftXiaMiantong_Jicaitong.name = "左側下面銅+基材銅";
  320. leftXiaMiantong_Jicaitong.ID = "100154";
  321. leftXiaMiantong_Jicaitong.aliasName = "BRTMTH";
  322. leftShangMiantong.name = "左側上面銅";
  323. leftShangMiantong.ID = "100155";
  324. leftShangMiantong.aliasName = "YXCKZF";
  325. leftXiaMiantong.name = "左側下面銅";
  326. leftXiaMiantong.ID = "100156";
  327. leftXiaMiantong.aliasName = "ABLLTX";
  328. leftKongtong.name = "左側孔銅";
  329. leftKongtong.drawType = "MeasureHLine";
  330. leftKongtong.ID = "100157";
  331. leftKongtong.aliasName = "RJVFMC";
  332. leftJiaoneisuo.name = "左側膠内縮";
  333. leftJiaoneisuo.drawType = "MeasureHLine";
  334. leftJiaoneisuo.ID = "300168";
  335. leftJiaoneisuo.aliasName = "XJSSRG";
  336. rightShangJicaitong.name = "右側上基材銅";
  337. rightShangJicaitong.ID = "100158";
  338. rightShangJicaitong.aliasName = "ZEASAC";
  339. rightXiaJicaitong.name = "右側下基材銅";
  340. rightXiaJicaitong.ID = "100159";
  341. rightXiaJicaitong.aliasName = "NULVEP";
  342. rightShangMiantong_Jicaitong.name = "右側上面銅+基材銅";
  343. rightShangMiantong_Jicaitong.ID = "100160";
  344. rightShangMiantong_Jicaitong.aliasName = "LQEEIH";
  345. rightXiaMiantong_Jicaitong.name = "右側下面銅+基材銅";
  346. rightXiaMiantong_Jicaitong.ID = "100161";
  347. rightXiaMiantong_Jicaitong.aliasName = "RZQRLW";
  348. rightShangMiantong.name = "右側上面銅";
  349. rightShangMiantong.ID = "100162";
  350. rightShangMiantong.aliasName = "BCUPMA";
  351. rightXiaMiantong.name = "右側下面銅";
  352. rightXiaMiantong.ID = "100163";
  353. rightXiaMiantong.aliasName = "LQWSEW";
  354. rightKongtong.name = "右側孔銅";
  355. rightKongtong.drawType = "MeasureHLine";
  356. rightKongtong.ID = "100164";
  357. rightKongtong.aliasName = "XJSSRE";
  358. rightJiaoneisuo.name = "右側膠内縮";
  359. rightJiaoneisuo.drawType = "MeasureHLine";
  360. rightJiaoneisuo.ID = "300167";
  361. rightJiaoneisuo.aliasName = "XJSSRF";
  362. shangKongjing.name = "上孔徑";
  363. shangKongjing.drawType = "MeasureHLine";
  364. shangKongjing.ID = "100165";
  365. shangKongjing.aliasName = "IBTYKT";
  366. xiaKongjing.name = "下孔徑";
  367. xiaKongjing.drawType = "MeasureHLine";
  368. xiaKongjing.ID = "100166";
  369. xiaKongjing.aliasName = "KDJMHF";
  370. dataInfors.Add(leftShangJicaitong);
  371. dataInfors.Add(leftXiaJicaitong);
  372. dataInfors.Add(leftShangMiantong_Jicaitong);
  373. dataInfors.Add(leftXiaMiantong_Jicaitong);
  374. dataInfors.Add(leftShangMiantong);
  375. dataInfors.Add(leftXiaMiantong);
  376. dataInfors.Add(leftKongtong);
  377. dataInfors.Add(leftJiaoneisuo);
  378. dataInfors.Add(rightShangJicaitong);
  379. dataInfors.Add(rightXiaJicaitong);
  380. dataInfors.Add(rightShangMiantong_Jicaitong);
  381. dataInfors.Add(rightXiaMiantong_Jicaitong);
  382. dataInfors.Add(rightShangMiantong);
  383. dataInfors.Add(rightXiaMiantong);
  384. dataInfors.Add(rightKongtong);
  385. dataInfors.Add(rightJiaoneisuo);
  386. dataInfors.Add(shangKongjing);
  387. dataInfors.Add(xiaKongjing);
  388. number = 16;
  389. success = 0;
  390. wrongNumber = number;
  391. }
  392. public override void Compute(Mat image, bool isCropFlag, int X, int Y)
  393. {
  394. Initialize();
  395. Ceju ceju = new Ceju();
  396. Mat cropEdge = new Mat();
  397. int[] y = new int[2];
  398. int[] b = new int[4];
  399. ceju.Crop2(image, out cropEdge, out y, out b, /*true 避免4(9)4(12)和7(10)这样目标区域过于靠下区域的图片定位下面铜错误*/isCropFlag);
  400. //待自测scc-4if (!isCropFlag && y[1] + 300 == image.Rows)
  401. // ceju.Crop2(image, out cropEdge, out y, out b, true/*isCropFlag*/);
  402. Mat cropEdgeLeft = cropEdge[0, cropEdge.Rows - 1, b[0], b[1]];
  403. Mat cropEdgeRight = cropEdge[0, cropEdge.Rows - 1, b[2], b[3]];
  404. Mat cropLeft = image[y[0], y[1], b[0], b[1]];
  405. Mat cropRight = image[y[0], y[1], b[2], b[3]];
  406. if (isCropFlag)
  407. {
  408. y[0] += Y;
  409. b[0] += X;
  410. b[2] += X;
  411. }
  412. ComputeLeft(cropLeft, cropEdgeLeft, image, y, b[0]);
  413. ComputeRight(cropRight, cropEdgeRight, image, y, b[2]);
  414. }
  415. private void ComputeLeft(Mat cropLeft, Mat cropCloseLeft, Mat image, int[] y, int border)
  416. {
  417. Ceju ceju = new Ceju();
  418. //获得蓝色,绿色,红色通道图片
  419. Mat[] bgr = Cv2.Split(cropLeft);
  420. Mat imageBlue = bgr[0];
  421. Mat imageGreen = bgr[1];
  422. Mat imageRed = bgr[2];
  423. //獲得目標區域
  424. Mat imageContour = new Mat();
  425. ceju.GetContour(imageRed, out imageContour);
  426. // 二、计算数据提取区域
  427. int[] dataArea = new int[2];
  428. ceju.GetDataArea(imageContour, out dataArea, "left");
  429. //dataArea[0] -= 50;
  430. dataArea[1] -= 30;
  431. int middleMianJicaitong = (dataArea[0] + dataArea[1]) / 2;
  432. int middleMiantong = (middleMianJicaitong + dataArea[1]) / 2;
  433. int middleJicaitong = (dataArea[0] + middleMianJicaitong) / 2;
  434. //提取綫條
  435. double ordinateL1 = 0;
  436. ceju.ExtractLines(imageContour, out ordinateL1, dataArea[0], dataArea[1], 1);
  437. double ordinateL3 = 0;
  438. ceju.ExtractLines(imageContour, out ordinateL3, dataArea[0], dataArea[1], ordinateL1, -1);
  439. //待自测scc-4_0_to delete and test
  440. leftShangMiantong_Jicaitong.Set(ordinateL3 - ordinateL1, middleMianJicaitong + border, (int)ordinateL1 + y[0], middleMianJicaitong + border, (int)ordinateL3 + y[0]);
  441. UpdateSuccessLine();
  442. double ordinateL6 = 0;
  443. ceju.ExtractLines2(imageContour, out ordinateL6, dataArea[0], dataArea[1], 1);
  444. double ordinateL4 = 0;
  445. ceju.ExtractLines2(imageContour, out ordinateL4, dataArea[0], dataArea[1], ordinateL6, -1);
  446. //待自测scc-4_0_to delete and test
  447. double ordinateL4Copy = 0;
  448. ceju.ExtractLines(imageContour, out ordinateL4Copy, middleMianJicaitong - 10, middleMianJicaitong + 10, ordinateL3, 1);
  449. if (ordinateL4Copy < ordinateL4)
  450. ordinateL4 = ordinateL4Copy;
  451. leftXiaMiantong_Jicaitong.Set(ordinateL6 - ordinateL4, middleMianJicaitong + border, (int)ordinateL4 + y[0], middleMianJicaitong + border, (int)ordinateL6 + y[0]);
  452. UpdateSuccessLine();
  453. //// 提取L2
  454. //double ordinateL2 = 0;
  455. //if (ordinateL1 + 10 < ordinateL3 - 10 && dataArea[0] < dataArea[1])
  456. //{
  457. // ceju.InsideLine(imageGreen, (int)ordinateL1 + 10, (int)ordinateL3 - 10, dataArea[0], dataArea[1], out ordinateL2, 1);
  458. // double[] ordinateL2_Acc = new double[] { ordinateL2, ordinateL2 };
  459. // ceju.InsideLine_Accuracy(imageGreen, (int)ordinateL1 + 10, (int)ordinateL3 - 10, dataArea[0], dataArea[1], middleMiantong, middleJicaitong
  460. // , ordinateL2, ordinateL2, out ordinateL2_Acc, 1, false);
  461. // leftShangMiantong.Set(ordinateL2_Acc[0] - ordinateL1, middleMiantong + border, (int)ordinateL1 + y[0], middleMiantong + border, (int)ordinateL2_Acc[0] + y[0]);
  462. // leftShangJicaitong.Set(ordinateL3 - ordinateL2_Acc[1], middleJicaitong + border, (int)ordinateL2_Acc[1] + y[0], middleJicaitong + border, (int)ordinateL3 + y[0]);
  463. // UpdateSuccessLine();
  464. // UpdateSuccessLine();
  465. //}
  466. //// 提取L5
  467. //double ordinateL5 = 0;
  468. //if (ordinateL4 + 10 < ordinateL6 - 10 && dataArea[0] < dataArea[1])
  469. //{
  470. // ceju.InsideLine(imageGreen, (int)ordinateL4 + 10, (int)ordinateL6 - 10, dataArea[0], dataArea[1], out ordinateL5, 2);
  471. // double[] ordinateL2_Acc = new double[] { ordinateL5, ordinateL5 };
  472. // ceju.InsideLine_Accuracy(imageGreen, (int)ordinateL4 + 10, (int)ordinateL6 - 10, dataArea[0], dataArea[1], middleMiantong, middleJicaitong
  473. // , ordinateL5, ordinateL5, out ordinateL2_Acc, 2, false);
  474. // leftXiaMiantong.Set(ordinateL6 - ordinateL2_Acc[0], middleMiantong + border, (int)ordinateL2_Acc[0] + y[0], middleMiantong + border, (int)ordinateL6 + y[0]);
  475. // leftXiaJicaitong.Set(ordinateL2_Acc[1] - ordinateL4, middleJicaitong + border, (int)ordinateL4 + y[0], middleJicaitong + border, (int)ordinateL2_Acc[1] + y[0]);
  476. // UpdateSuccessLine();
  477. // UpdateSuccessLine();
  478. //}
  479. //根据提取的面铜和基材铜,获取到孔铜和胶内缩后,根据胶内缩结果验证面铜和基材铜的横坐标,如果位置不符合规律,需要重新计算面铜和基材铜
  480. //待自测scc-4_0_to add and test
  481. //// 提取竪綫
  482. //double ordinateV1 = 0;
  483. //ceju.ExtractVerticalLinesR2L(cropCloseLeft, out ordinateV1, (int)ordinateL3, (int)ordinateL4);
  484. //double ordinateV2 = 0;
  485. //////精准找到面铜的标记点,避免直线拟合导致测量精度不够
  486. ////Mat mat1 = new Mat();
  487. ////Cv2.Normalize(imageContour, mat1, 0, 255, NormTypes.MinMax);
  488. ////Cv2.ImShow("imageContour", mat1);
  489. ////Cv2.WaitKey();
  490. //int[] result1 = ceju.ExtractVerticalLinesR2L(imageContour, out ordinateV2, (int)ordinateL3, (int)ordinateL4, ordinateV1);
  491. //int middle2 = (int)((ordinateL3 + ordinateL4) / 2);
  492. //leftKongtong.Set(ordinateV1 - ordinateV2, (int)ordinateV1 + border, middle2 + y[0], (int)ordinateV2 + border, middle2 + y[0]);
  493. UpdateSuccessLine();
  494. //待自测scc-4_0_to add and test
  495. //leftJiaoneisuo.Set(ordinateV2 - result1[0], (int)ordinateV2 + border, result1[1] + y[0], result1[0] + border, result1[1] + y[0]);
  496. //UpdateSuccessLine();
  497. ////待自测scc-4_0_to add and test
  498. //根据提取的面铜和基材铜,获取到孔铜和胶内缩后,根据胶内缩结果验证面铜和基材铜的横坐标,如果位置不符合规律,需要重新计算面铜和基材铜
  499. //if (ordinateV2 > middleMiantong + 5/*10*/)
  500. //{
  501. // leftShangMiantong_Jicaitong.Set(ordinateL3 - ordinateL1, middleMianJicaitong + border, (int)ordinateL1 + y[0], middleMianJicaitong + border, (int)ordinateL3 + y[0]);
  502. // UpdateSuccessLine();
  503. // leftXiaMiantong_Jicaitong.Set(ordinateL6 - ordinateL4, middleMianJicaitong + border, (int)ordinateL4 + y[0], middleMianJicaitong + border, (int)ordinateL6 + y[0]);
  504. // UpdateSuccessLine();
  505. //}
  506. //else
  507. //{//重新计算 面铜和基材铜
  508. // //dataArea[0] -= 50;
  509. // dataArea[1] = (int)ordinateV2 - 30;
  510. // //dataArea[1] -= 30;
  511. // dataArea[0] = dataArea[1] - 100;
  512. // middleMianJicaitong = (dataArea[0] + dataArea[1]) / 2;
  513. // middleMiantong = (middleMianJicaitong + dataArea[1]) / 2;
  514. // middleJicaitong = (dataArea[0] + middleMianJicaitong) / 2;
  515. // //提取綫條
  516. // ordinateL1 = 0;
  517. // ceju.ExtractLines(imageContour, out ordinateL1, dataArea[0], dataArea[1], 1);
  518. // ordinateL3 = 0;
  519. // ceju.ExtractLines(imageContour, out ordinateL3, dataArea[0], dataArea[1], ordinateL1, -1);
  520. // //leftShangMiantong_Jicaitong.Set(ordinateL3 - ordinateL1, middleMianJicaitong + border, (int)ordinateL1 + y[0], middleMianJicaitong + border, (int)ordinateL3 + y[0]);
  521. // //UpdateSuccessLine();
  522. // ordinateL6 = 0;
  523. // ceju.ExtractLines2(imageContour, out ordinateL6, dataArea[0], dataArea[1], 1);
  524. // ordinateL4 = 0;
  525. // ceju.ExtractLines2(imageContour, out ordinateL4, dataArea[0], dataArea[1], ordinateL6, -1);
  526. // leftShangMiantong_Jicaitong.Set(ordinateL3 - ordinateL1, middleMianJicaitong + border, (int)ordinateL1 + y[0], middleMianJicaitong + border, (int)ordinateL3 + y[0]);
  527. // UpdateSuccessLine();
  528. // leftXiaMiantong_Jicaitong.Set(ordinateL6 - ordinateL4, middleMianJicaitong + border, (int)ordinateL4 + y[0], middleMianJicaitong + border, (int)ordinateL6 + y[0]);
  529. // UpdateSuccessLine();
  530. //}
  531. // 提取L2
  532. double ordinateL2 = 0;
  533. if (ordinateL1 + 10 < ordinateL3 - 10 && dataArea[0] < dataArea[1])
  534. {
  535. ceju.InsideLine(imageGreen, (int)ordinateL1 + 10, (int)ordinateL3 - 10, dataArea[0], dataArea[1], out ordinateL2, 1);
  536. double[] ordinateL2_Acc = new double[] { ordinateL2, ordinateL2 };
  537. ceju.InsideLine_Accuracy(imageGreen, (int)ordinateL1 + 10, (int)ordinateL3 - 10, dataArea[0], dataArea[1], middleMiantong, middleJicaitong
  538. , ordinateL2, ordinateL2, out ordinateL2_Acc, 1, 2, false);
  539. //纠正02781的偏差,避免出现斜对角抖动过大的问题
  540. if (Math.Abs(ordinateL2_Acc[0] - ordinateL2_Acc[1]) * 2 > Math.Abs(middleMiantong - middleJicaitong) - 2)
  541. //if (ordinateL2_Acc[0] == ordinateL2 || ordinateL2_Acc[0] == ordinateL2) ordinateL2_Acc = new double[] { ordinateL2, ordinateL2 };
  542. if (Math.Abs(ordinateL2_Acc[0]- (ordinateL1+ordinateL3)/2) < Math.Abs(ordinateL2_Acc[1]- (ordinateL1+ordinateL3)/2)) ordinateL2_Acc[1] = ordinateL2_Acc[0];
  543. else ordinateL2_Acc[0] = ordinateL2_Acc[1];
  544. leftShangMiantong.Set(ordinateL2_Acc[0] - ordinateL1, middleMiantong + border, (int)ordinateL1 + y[0], middleMiantong + border, (int)ordinateL2_Acc[0] + y[0]);
  545. leftShangJicaitong.Set(ordinateL3 - ordinateL2_Acc[1], middleJicaitong + border, (int)ordinateL2_Acc[1] + y[0], middleJicaitong + border, (int)ordinateL3 + y[0]);
  546. UpdateSuccessLine();
  547. UpdateSuccessLine();
  548. }
  549. // 提取L5
  550. double ordinateL5 = 0;
  551. if (ordinateL4 + 10 < ordinateL6 - 10 && dataArea[0] < dataArea[1])
  552. {
  553. /*double ordinateL5_2 = */ceju.InsideLine(imageGreen, (int)ordinateL4 + 10, (int)ordinateL6 - 10, dataArea[0], dataArea[1], out ordinateL5, 2, true);
  554. double[] ordinateL2_Acc = new double[] { ordinateL5, ordinateL5 };
  555. ceju.InsideLine_Accuracy(imageGreen, (int)ordinateL4 + 10, (int)ordinateL6 - 10, dataArea[0], dataArea[1], middleMiantong, middleJicaitong
  556. , ordinateL5, ordinateL5, out ordinateL2_Acc, 2, 2, true);
  557. if (Math.Abs(ordinateL2_Acc[0] - ordinateL2_Acc[1]) * 2 > Math.Abs(middleMiantong - middleJicaitong) - 2)
  558. if (Math.Abs(ordinateL2_Acc[0]- (ordinateL4+ordinateL6)/2) < Math.Abs(ordinateL2_Acc[1]- (ordinateL4+ordinateL6)/2)) ordinateL2_Acc[1] = ordinateL2_Acc[0];
  559. else ordinateL2_Acc[0] = ordinateL2_Acc[1];
  560. //if (ordinateL2_Acc[0] == 0 && ordinateL2_Acc[1] == 0)
  561. //{
  562. // ordinateL2_Acc[0] = (ordinateL6 * 3 + ordinateL4) / 4;
  563. // ordinateL2_Acc[1] = ordinateL2_Acc[0];
  564. //}
  565. if (ordinateL2_Acc[0] == 0 && ordinateL2_Acc[1] == 0)
  566. {//重新测定
  567. ordinateL2_Acc[0] = (ordinateL6 * 3 + ordinateL4) / 4;
  568. ordinateL2_Acc[1] = ordinateL2_Acc[0];
  569. leftXiaMiantong.Set(ordinateL6 - ordinateL2_Acc[0], middleMiantong + border, (int)ordinateL2_Acc[0] + y[0], middleMiantong + border, (int)ordinateL6 + y[0]);
  570. leftXiaJicaitong.Set(ordinateL2_Acc[1] - ordinateL4, middleJicaitong + border, (int)ordinateL4 + y[0], middleJicaitong + border, (int)ordinateL2_Acc[1] + y[0]);
  571. UpdateSuccessLine();
  572. UpdateSuccessLine();
  573. try
  574. {
  575. // 二、计算数据提取区域
  576. int[] dataArea_2 = new int[2];
  577. //ceju.GetDataArea(imageContour, out dataArea, "left");
  578. ////dataArea[0] -= 50;
  579. dataArea_2[0] = dataArea[1] - 10;
  580. dataArea_2[1] = dataArea_2[0] + dataArea[1] - dataArea[0];
  581. int middleMianJicaitong_2 = (dataArea_2[0] + dataArea_2[1]) / 2;
  582. int middleMiantong_2 = (middleMianJicaitong_2 + dataArea_2[1]) / 2;
  583. int middleJicaitong_2 = (dataArea_2[0] + middleMianJicaitong_2) / 2;
  584. ceju.ExtractLines2(imageContour, out ordinateL6, dataArea_2[0], dataArea_2[1], 1);
  585. //double ordinateL4 = 0;
  586. //ceju.ExtractLines2(imageContour, out ordinateL4, dataArea[0], dataArea[1], ordinateL6, -1);
  587. ceju.InsideLine(imageGreen, (int)ordinateL4 + 10, (int)ordinateL6 - 10, dataArea_2[0], dataArea_2[1], out ordinateL5, 2);
  588. if (ordinateL5 != 0)
  589. {
  590. ordinateL2_Acc = new double[] { ordinateL5, ordinateL5 };
  591. ceju.InsideLine_Accuracy(imageGreen, (int)ordinateL4 + 10, (int)ordinateL6 - 10, dataArea_2[0], dataArea_2[1], middleMiantong, middleJicaitong
  592. , ordinateL5, ordinateL5, out ordinateL2_Acc, 2, 2, false);
  593. }
  594. leftXiaMiantong_Jicaitong.Set(ordinateL6 - ordinateL4, middleMianJicaitong_2 + border, (int)ordinateL4 + y[0], middleMianJicaitong_2 + border, (int)ordinateL6 + y[0]);
  595. UpdateSuccessLine();
  596. leftXiaMiantong.Set(ordinateL6 - ordinateL2_Acc[0], middleMiantong_2 + border, (int)ordinateL2_Acc[0] + y[0], middleMiantong_2 + border, (int)ordinateL6 + y[0]);
  597. leftXiaJicaitong.Set(ordinateL2_Acc[1] - ordinateL4, middleJicaitong_2 + border, (int)ordinateL4 + y[0], middleJicaitong_2 + border, (int)ordinateL2_Acc[1] + y[0]);
  598. UpdateSuccessLine();
  599. UpdateSuccessLine();
  600. }
  601. catch (Exception)
  602. {
  603. }
  604. }
  605. else
  606. {
  607. leftXiaMiantong.Set(ordinateL6 - ordinateL2_Acc[0], middleMiantong + border, (int)ordinateL2_Acc[0] + y[0], middleMiantong + border, (int)ordinateL6 + y[0]);
  608. leftXiaJicaitong.Set(ordinateL2_Acc[1] - ordinateL4, middleJicaitong + border, (int)ordinateL4 + y[0], middleJicaitong + border, (int)ordinateL2_Acc[1] + y[0]);
  609. UpdateSuccessLine();
  610. UpdateSuccessLine();
  611. }
  612. }
  613. //待自测scc-4_0_to delete and test
  614. // 提取竪綫
  615. double ordinateV1 = 0;
  616. ceju.ExtractVerticalLinesR2L(cropCloseLeft, out ordinateV1, (int)ordinateL3, (int)ordinateL4);
  617. double ordinateV2 = 0;
  618. int[] result1 = ceju.ExtractVerticalLinesR2L(imageContour, out ordinateV2, (int)ordinateL3, (int)ordinateL4, ordinateV1);
  619. int middle2 = (int)((ordinateL3 + ordinateL4) / 2);
  620. leftKongtong.Set(ordinateV1 - ordinateV2, (int)ordinateV1 + border, middle2 + y[0], (int)ordinateV2 + border, middle2 + y[0]);
  621. UpdateSuccessLine();
  622. leftJiaoneisuo.Set(ordinateV2 - result1[0], (int)ordinateV2 + border, result1[1] + y[0], result1[0] + border, result1[1] + y[0]);
  623. UpdateSuccessLine();
  624. double ordinateV1Upper = 0;
  625. ceju.ExtractVerticalLinesR2L(cropCloseLeft, out ordinateV1Upper, (int)ordinateL3 + 10, (int)ordinateL3 + 20);
  626. double ordinateV2Upper = 0;
  627. ceju.ExtractVerticalLinesR2L(imageContour, out ordinateV2Upper, (int)ordinateL3 + 10, (int)ordinateL3 + 20, ordinateV1Upper);
  628. double ordinateV1Lower = 0;
  629. ceju.ExtractVerticalLinesR2L(cropCloseLeft, out ordinateV1Lower, (int)ordinateL4 - 20, (int)ordinateL4 - 10);
  630. double ordinateV2Lower = 0;
  631. ceju.ExtractVerticalLinesR2L(imageContour, out ordinateV2Lower, (int)ordinateL4 - 20, (int)ordinateL4 - 10, ordinateV1Lower);
  632. shangKongjing.point1 = new System.Drawing.Point((int)ordinateV2Upper + border, (int)ordinateL1 - 10 + y[0]);
  633. xiaKongjing.point1 = new System.Drawing.Point((int)ordinateV2Lower + border, (int)ordinateL6 + 10 + y[0]);
  634. }
  635. private void ComputeRight(Mat cropRight, Mat cropCloseRight, Mat image, int[] y, int border)
  636. {
  637. Ceju ceju = new Ceju();
  638. //获得蓝色,绿色,红色通道图片
  639. Mat[] bgr = Cv2.Split(cropRight);
  640. Mat imageBlue = bgr[0];
  641. Mat imageGreen = bgr[1];
  642. Mat imageRed = bgr[2];
  643. //獲得目標區域
  644. Mat imageContour = new Mat();
  645. ceju.GetContour(imageRed, out imageContour);
  646. // 二、计算数据提取区域
  647. int[] dataArea = new int[2];
  648. ceju.GetDataArea(imageContour, out dataArea, "right");
  649. dataArea[0] += 50;
  650. dataArea[1] += 20;
  651. int middleMianJicaitong = (dataArea[0] + dataArea[1]) / 2;
  652. int middleMiantong = (middleMianJicaitong + dataArea[1]) / 2;
  653. int middleJicaitong = (dataArea[0] + middleMianJicaitong) / 2;
  654. //提取綫條
  655. double ordinateL1 = 0;
  656. ceju.ExtractLines(imageContour, out ordinateL1, dataArea[0], dataArea[1], 1);
  657. double ordinateL3 = 0;
  658. ceju.ExtractLines(imageContour, out ordinateL3, dataArea[0], dataArea[1], ordinateL1, -1);
  659. rightShangMiantong_Jicaitong.Set(ordinateL3 - ordinateL1, middleMianJicaitong + border, (int)ordinateL1 + y[0], middleMianJicaitong + border, (int)ordinateL3 + y[0]);
  660. UpdateSuccessLine();
  661. double ordinateL6 = 0;
  662. ceju.ExtractLines2(imageContour, out ordinateL6, dataArea[0], dataArea[1], 1);
  663. double ordinateL4 = 0;
  664. ceju.ExtractLines2(imageContour, out ordinateL4, dataArea[0], dataArea[1], ordinateL6, -1);
  665. rightXiaMiantong_Jicaitong.Set(ordinateL6 - ordinateL4, middleMianJicaitong + border, (int)ordinateL4 + y[0], middleMianJicaitong + border, (int)ordinateL6 + y[0]);
  666. UpdateSuccessLine();
  667. // 四、提取L2
  668. double ordinateL2 = 0;
  669. if (ordinateL1 + 10 < ordinateL3 - 10 && dataArea[0] < dataArea[1])
  670. {
  671. ceju.InsideLine(imageGreen, (int)ordinateL1 + 10, (int)ordinateL3 - 10, dataArea[0], dataArea[1], out ordinateL2, 1/*, false*/);
  672. double[] ordinateL2_Acc = new double[] { ordinateL2 - 10, ordinateL2 -10 };
  673. ceju.InsideLine_Accuracy(imageGreen, (int)ordinateL1 + 10, (int)ordinateL3 - 10, dataArea[0], dataArea[1], middleMiantong, middleJicaitong
  674. , ordinateL2 /* 待自测scc-5_0_to debug and test- 5 */, ordinateL2 /*待自测scc-5_0_to debug and test- 5*/, out ordinateL2_Acc, 1, 2, false/* 待自测scc-5_0_to debug and test false */);
  675. ////精准找到面铜的标记点,避免直线拟合导致测量精度不够
  676. //Mat mat1 = new Mat();
  677. //Cv2.Normalize(imageGreen, mat1, 0, 255, NormTypes.MinMax);
  678. //Cv2.ImShow("imageGreen", mat1);
  679. //Cv2.WaitKey();
  680. rightShangMiantong.Set(ordinateL2_Acc[0] - ordinateL1, middleMiantong + border, (int)ordinateL1 + y[0], middleMiantong + border, (int)ordinateL2_Acc[0] + y[0]);
  681. rightShangJicaitong.Set(ordinateL3 - ordinateL2_Acc[1], middleJicaitong + border, (int)ordinateL2_Acc[1] + y[0], middleJicaitong + border, (int)ordinateL3 + y[0]);
  682. UpdateSuccessLine();
  683. UpdateSuccessLine();
  684. }
  685. // 五、提取L5
  686. double ordinateL5 = 0;
  687. if (ordinateL4 + 10 < ordinateL6 - 10 && dataArea[0] < dataArea[1])
  688. {
  689. ceju.InsideLine(imageGreen, (int)ordinateL4 + 10, (int)ordinateL6 - 10, dataArea[0], dataArea[1], out ordinateL5, 2/*, true*/);
  690. //Mat mat1 = new Mat();
  691. //Cv2.Normalize(imageGreen, mat1, 0, 255, NormTypes.MinMax);
  692. //Cv2.ImShow("imageGreen", mat1);
  693. //Cv2.WaitKey();
  694. double[] ordinateL2_Acc = new double[] { ordinateL5, ordinateL5 };
  695. //待自测scc-5_0_to delete and test
  696. ceju.InsideLine_Accuracy(imageGreen, (int)ordinateL4 + 10, (int)ordinateL6 - 10, dataArea[0], dataArea[1], middleMiantong, middleJicaitong
  697. , ordinateL5, ordinateL5, out ordinateL2_Acc, 2, 2, false);
  698. rightXiaMiantong.Set(ordinateL6 - ordinateL2_Acc[0], middleMiantong + border, (int)ordinateL2_Acc[0] + y[0], middleMiantong + border, (int)ordinateL6 + y[0]);
  699. rightXiaJicaitong.Set(ordinateL2_Acc[1] - ordinateL4, middleJicaitong + border, (int)ordinateL4 + y[0], middleJicaitong + border, (int)ordinateL2_Acc[1] + y[0]);
  700. UpdateSuccessLine();
  701. UpdateSuccessLine();
  702. }
  703. //Cv2.ImWrite(@"C:\Users\54434\Desktop\imageContour.png", imageContour * 127);
  704. //提取竪綫
  705. double ordinateV1 = 0;
  706. double ordinateV2 = 0;
  707. int[] result1 = new int[] { 0, 0 };
  708. try
  709. {
  710. //解决两层板有些孔铜找不到的问题
  711. int verMargin = 20;
  712. if (ordinateL4 - ordinateL3 < 20)
  713. verMargin = 0;
  714. else if (ordinateL4 - ordinateL3 < 40)
  715. verMargin = 10;
  716. ceju.ExtractVerticalLinesL2R(cropCloseRight, out ordinateV1, (int)ordinateL3 + verMargin, (int)ordinateL4 - verMargin);
  717. result1 = ceju.ExtractVerticalLinesL2R(imageContour, out ordinateV2, (int)ordinateL3 + verMargin, (int)ordinateL4 - verMargin, ordinateV1, false);
  718. }
  719. catch (Exception)
  720. {
  721. }
  722. int middle2 = (int)((ordinateL3 + ordinateL4) / 2);
  723. rightKongtong.Set(ordinateV2 - ordinateV1, (int)ordinateV1 + border, middle2 + y[0], (int)ordinateV2 + border, middle2 + y[0]);
  724. UpdateSuccessLine();
  725. rightJiaoneisuo.Set(result1[0] - ordinateV2, (int)ordinateV2 + border, result1[1] + y[0], result1[0] + border, result1[1] + y[0]);
  726. UpdateSuccessLine();
  727. double ordinateV1Upper = 0;
  728. ceju.ExtractVerticalLinesL2R(cropCloseRight, out ordinateV1Upper, (int)ordinateL3 + 10, (int)ordinateL3 + 20);
  729. double ordinateV2Upper = 0;
  730. ceju.ExtractVerticalLinesL2R(imageContour, out ordinateV2Upper, (int)ordinateL3 + 10, (int)ordinateL3 + 20, ordinateV1Upper);
  731. double ordinateV1Lower = 0;
  732. ceju.ExtractVerticalLinesL2R(cropCloseRight, out ordinateV1Lower, (int)ordinateL4 - 20, (int)ordinateL4 - 10);
  733. double ordinateV2Lower = 0;
  734. ceju.ExtractVerticalLinesL2R(imageContour, out ordinateV2Lower, (int)ordinateL4 - 20, (int)ordinateL4 - 10, ordinateV1Lower);
  735. shangKongjing.point2 = new System.Drawing.Point((int)ordinateV2Upper + border, (int)ordinateL1 - 10 + y[0]);
  736. xiaKongjing.point2 = new System.Drawing.Point((int)ordinateV2Lower + border, (int)ordinateL6 + 10 + y[0]);
  737. if (xiaKongjing.point1.Y != xiaKongjing.point2.Y)
  738. {
  739. int kongjingY = Math.Max(xiaKongjing.point1.Y, xiaKongjing.point2.Y);
  740. xiaKongjing.point1.Y = kongjingY;
  741. xiaKongjing.point2.Y = kongjingY;
  742. }
  743. shangKongjing.value = shangKongjing.point2.X - shangKongjing.point1.X;
  744. xiaKongjing.value = xiaKongjing.point2.X - xiaKongjing.point1.X;
  745. UpdateSuccessLine();
  746. UpdateSuccessLine();
  747. }
  748. }
  749. public class SancengbanYou : AutoMeasureAnalysis
  750. {
  751. public DataInfor shangJicaitong = new DataInfor();
  752. public DataInfor xiaJicaitong = new DataInfor();
  753. public DataInfor shangMiantong_Jicaitong = new DataInfor();
  754. public DataInfor xiaMiantong_Jicaitong = new DataInfor();
  755. public DataInfor shangMiantong = new DataInfor();
  756. public DataInfor xiaMiantong = new DataInfor();
  757. public DataInfor cucaodu = new DataInfor();
  758. public DataInfor shangKongtong = new DataInfor();
  759. public DataInfor xiaKongtong = new DataInfor();
  760. private void Initialize()
  761. {
  762. dataInfors = new List<DataInfor>();
  763. shangJicaitong.name = "上基材銅";
  764. shangJicaitong.ID = "100104";
  765. shangJicaitong.aliasName = "BGHYOX";
  766. xiaJicaitong.name = "下基材銅";
  767. xiaJicaitong.ID = "100105";
  768. xiaJicaitong.aliasName = "BGWDNC";
  769. shangMiantong_Jicaitong.name = "上面銅+基材銅";
  770. shangMiantong_Jicaitong.ID = "100106";
  771. shangMiantong_Jicaitong.aliasName = "SQMNJW";
  772. xiaMiantong_Jicaitong.name = "下面銅+基材銅";
  773. xiaMiantong_Jicaitong.ID = "100107";
  774. xiaMiantong_Jicaitong.aliasName = "CVJYIF";
  775. shangMiantong.name = "上面銅";
  776. shangMiantong.ID = "100108";
  777. shangMiantong.aliasName = "MJLBAA";
  778. xiaMiantong.name = "下面銅";
  779. xiaMiantong.ID = "100109";
  780. xiaMiantong.aliasName = "ZCHBNJ";
  781. cucaodu.name = "粗糙度";
  782. cucaodu.drawType = "MeasureHLine";
  783. cucaodu.ID = "100110";
  784. cucaodu.aliasName = "QDTTQQ";
  785. shangKongtong.name = "上孔銅";
  786. shangKongtong.ID = "100111";
  787. shangKongtong.aliasName = "UIKKYT";
  788. shangKongtong.drawType = "MeasureHLine";
  789. xiaKongtong.name = "下孔銅";
  790. xiaKongtong.ID = "100112";
  791. xiaKongtong.aliasName = "SIRZJN";
  792. xiaKongtong.drawType = "MeasureHLine";
  793. dataInfors.Add(shangJicaitong);
  794. dataInfors.Add(xiaJicaitong);
  795. dataInfors.Add(shangMiantong_Jicaitong);
  796. dataInfors.Add(xiaMiantong_Jicaitong);
  797. dataInfors.Add(shangMiantong);
  798. dataInfors.Add(xiaMiantong);
  799. dataInfors.Add(cucaodu);
  800. dataInfors.Add(shangKongtong);
  801. dataInfors.Add(xiaKongtong);
  802. number = 9;
  803. success = 0;
  804. wrongNumber = number;
  805. }
  806. public override void Compute(Mat image, bool isCropFlag, int X, int Y)
  807. {
  808. Initialize();
  809. Ceju ceju = new Ceju();
  810. Mat cropEdge = new Mat();
  811. int[] y = new int[2];
  812. int[] b = new int[4];
  813. ceju.Crop2(image, out cropEdge, out y, out b, isCropFlag);
  814. //分割
  815. Mat cropEdgeRight = cropEdge[0, cropEdge.Rows - 1, b[2], b[3]];//用於測量邊緣竪綫
  816. Mat cropRight = image[y[0], y[1], b[2], b[3]];
  817. if (isCropFlag)
  818. {
  819. y[0] += Y;
  820. b[2] += X;
  821. }
  822. ComputeRight(cropRight, cropEdgeRight, image, y, b[2]);
  823. }
  824. private void ComputeRight(Mat cropRight, Mat cropEdgeRight, Mat image, int[] y, int border)
  825. {
  826. Ceju ceju = new Ceju();
  827. //获得蓝色,绿色,红色通道图片
  828. Mat[] bgr = Cv2.Split(cropRight);
  829. Mat imageBlue = bgr[0];
  830. Mat imageGreen = bgr[1];
  831. Mat imageRed = bgr[2];
  832. //獲得目標區域
  833. Mat imageContour = new Mat();
  834. ceju.GetContour(imageRed, out imageContour);
  835. // 计算数据提取区域
  836. int[] dataArea = new int[2];
  837. ceju.GetDataArea(imageContour, out dataArea, "right");
  838. dataArea[0] += 30;
  839. //dataArea[1] += 50;
  840. int middleMianJicaitong = (dataArea[0] + dataArea[1]) / 2;
  841. int middleMiantong = (middleMianJicaitong + dataArea[1]) / 2;
  842. int middleJicaitong = (dataArea[0] + middleMianJicaitong) / 2;
  843. //提取綫條
  844. double ordinateL1 = 0;
  845. ceju.ExtractLines(imageContour, out ordinateL1, dataArea[0], dataArea[1], 1);
  846. double ordinateL3 = 0;
  847. ceju.ExtractLines(imageContour, out ordinateL3, dataArea[0], dataArea[1], ordinateL1, -1);
  848. shangMiantong_Jicaitong.Set(ordinateL3 - ordinateL1, middleMianJicaitong + border, (int)ordinateL1 + y[0], middleMianJicaitong + border, (int)ordinateL3 + y[0]);
  849. UpdateSuccessLine();
  850. double ordinateL4 = 0;
  851. ceju.ExtractLines(imageContour, out ordinateL4, dataArea[0], dataArea[1], ordinateL3, 1);
  852. double ordinateL5 = 0;
  853. ceju.ExtractLines(imageContour, out ordinateL5, dataArea[0], dataArea[1], ordinateL4, -1);
  854. double ordinateL8 = 0;
  855. ceju.ExtractLines2(imageContour, out ordinateL8, dataArea[0], dataArea[1], 1);
  856. double ordinateL6 = 0;
  857. ceju.ExtractLines2(imageContour, out ordinateL6, dataArea[0], dataArea[1], ordinateL8, -1);
  858. xiaMiantong_Jicaitong.Set(ordinateL8 - ordinateL6, middleMianJicaitong + border, (int)ordinateL6 + y[0], middleMianJicaitong + border, (int)ordinateL8 + y[0]);
  859. UpdateSuccessLine();
  860. // 四、提取L2
  861. double ordinateL2 = 0;
  862. if (ordinateL1 + 10 < ordinateL3 - 10 && dataArea[0] < dataArea[1])
  863. {
  864. ceju.InsideLine(imageGreen, (int)ordinateL1 + 10, (int)ordinateL3 - 10, dataArea[0], dataArea[1], out ordinateL2);
  865. shangMiantong.Set(ordinateL2 - ordinateL1, middleMiantong + border, (int)ordinateL1 + y[0], middleMiantong + border, (int)ordinateL2 + y[0]);
  866. shangJicaitong.Set(ordinateL3 - ordinateL2, middleJicaitong + border, (int)ordinateL2 + y[0], middleJicaitong + border, (int)ordinateL3 + y[0]);
  867. UpdateSuccessLine();
  868. UpdateSuccessLine();
  869. }
  870. // 五、提取L7
  871. double ordinateL7 = 0;
  872. if (ordinateL6 + 10 < ordinateL8 - 10 && dataArea[0] < dataArea[1])
  873. {
  874. ceju.InsideLine(imageGreen, (int)ordinateL6 + 10, (int)ordinateL8 - 10, dataArea[0], dataArea[1], out ordinateL7);
  875. xiaMiantong.Set(ordinateL8 - ordinateL7, middleMiantong + border, (int)ordinateL7 + y[0], middleMiantong + border, (int)ordinateL8 + y[0]);
  876. xiaJicaitong.Set(ordinateL7 - ordinateL6, middleJicaitong + border, (int)ordinateL6 + y[0], middleJicaitong + border, (int)ordinateL7 + y[0]);
  877. UpdateSuccessLine();
  878. UpdateSuccessLine();
  879. }
  880. //提取竪綫
  881. double ordinateV1 = 0;
  882. ceju.ExtractVerticalLinesL2R(cropEdgeRight, out ordinateV1, (int)ordinateL3 + 20, (int)ordinateL3 + 40);
  883. double ordinateV2 = 0;
  884. ceju.ExtractVerticalLinesL2R(imageContour, out ordinateV2, (int)ordinateL3 + 20, (int)ordinateL3 + 40, ordinateV1);
  885. shangKongtong.Set(ordinateV2 - ordinateV1, (int)ordinateV1 + border, (int)ordinateL3 + 30 + y[0], (int)ordinateV2 + border, (int)ordinateL3 + 30 + y[0]);
  886. UpdateSuccessLine();
  887. double ordinateV3 = 0;
  888. ceju.ExtractVerticalLinesL2R(cropEdgeRight, out ordinateV3, (int)ordinateL6 - 40, (int)ordinateL6 - 20);
  889. double ordinateV4 = 0;
  890. ceju.ExtractVerticalLinesL2R(imageContour, out ordinateV4, (int)ordinateL6 - 40, (int)ordinateL6 - 20, ordinateV3);
  891. xiaKongtong.Set(ordinateV4 - ordinateV3, (int)ordinateV3 + border, (int)ordinateL6 - 30 + y[0], (int)ordinateV4 + border, (int)ordinateL6 - 30 + y[0]);
  892. UpdateSuccessLine();
  893. //計算粗糙度
  894. int roughness;
  895. int[] roughnessOrdinate = new int[2];
  896. ceju.GetSancengRoughness(imageContour, imageRed, (int)ordinateL3, (int)ordinateL4, (int)ordinateL5, (int)ordinateL6,
  897. (int)ordinateV2, (int)ordinateV4, dataArea, "right", out roughness, out roughnessOrdinate);
  898. cucaodu.Set(roughness, roughnessOrdinate[0] + border, roughnessOrdinate[1] + y[0], roughnessOrdinate[2] + border, roughnessOrdinate[3] + y[0]);
  899. UpdateSuccessLine();
  900. }
  901. }
  902. public class SancengbanZuo : AutoMeasureAnalysis
  903. {
  904. public DataInfor shangJicaitong = new DataInfor();
  905. public DataInfor xiaJicaitong = new DataInfor();
  906. public DataInfor shangMiantong_Jicaitong = new DataInfor();
  907. public DataInfor xiaMiantong_Jicaitong = new DataInfor();
  908. public DataInfor shangMiantong = new DataInfor();
  909. public DataInfor xiaMiantong = new DataInfor();
  910. public DataInfor cucaodu = new DataInfor();
  911. public DataInfor shangKongtong = new DataInfor();
  912. public DataInfor xiaKongtong = new DataInfor();
  913. private void Initialize()
  914. {
  915. dataInfors = new List<DataInfor>();
  916. shangJicaitong.name = "上基材銅";
  917. shangJicaitong.ID = "100094";
  918. shangJicaitong.aliasName = "BURQWZ";
  919. xiaJicaitong.name = "下基材銅";
  920. xiaJicaitong.ID = "100095";
  921. xiaJicaitong.aliasName = "CJQGSX";
  922. shangMiantong_Jicaitong.name = "上面銅+基材銅";
  923. shangMiantong_Jicaitong.ID = "100096";
  924. shangMiantong_Jicaitong.aliasName = "PCNGFF";
  925. xiaMiantong_Jicaitong.name = "下面銅+基材銅";
  926. xiaMiantong_Jicaitong.ID = "100097";
  927. xiaMiantong_Jicaitong.aliasName = "ONRAHR";
  928. shangMiantong.name = "上面銅";
  929. shangMiantong.ID = "100098";
  930. shangMiantong.aliasName = "BHTPXN";
  931. xiaMiantong.name = "下面銅";
  932. xiaMiantong.ID = "100099";
  933. xiaMiantong.aliasName = "RHZRXH";
  934. cucaodu.name = "粗糙度";
  935. cucaodu.drawType = "MeasureHLine";
  936. cucaodu.ID = "100100";
  937. cucaodu.aliasName = "PCTABZ";
  938. shangKongtong.name = "上孔銅";
  939. shangKongtong.drawType = "MeasureHLine";
  940. shangKongtong.ID = "100101";
  941. shangKongtong.aliasName = "IGTYVF";
  942. xiaKongtong.name = "下孔銅";
  943. xiaKongtong.drawType = "MeasureHLine";
  944. xiaKongtong.ID = "100102";
  945. xiaKongtong.aliasName = "KIVJLJ";
  946. dataInfors.Add(shangJicaitong);
  947. dataInfors.Add(xiaJicaitong);
  948. dataInfors.Add(shangMiantong_Jicaitong);
  949. dataInfors.Add(xiaMiantong_Jicaitong);
  950. dataInfors.Add(shangMiantong);
  951. dataInfors.Add(xiaMiantong);
  952. dataInfors.Add(cucaodu);
  953. dataInfors.Add(shangKongtong);
  954. dataInfors.Add(xiaKongtong);
  955. number = 9;
  956. success = 0;
  957. wrongNumber = number;
  958. }
  959. public override void Compute(Mat image, bool isCropFlag, int X, int Y)
  960. {
  961. Initialize();
  962. Ceju ceju = new Ceju();
  963. Mat cropEdge = new Mat();
  964. int[] y = new int[2];//上下裁剪边界
  965. int[] b = new int[4];//左右裁剪边界
  966. ceju.Crop2(image, out cropEdge, out y, out b, isCropFlag);
  967. Mat cropEdgeLeft = cropEdge[0, cropEdge.Rows - 1, b[0], b[1]];
  968. Mat cropLeft = image[y[0], y[1], b[0], b[1]];
  969. if (isCropFlag)
  970. {
  971. y[0] += Y;
  972. b[0] += X;
  973. }
  974. ComputeLeft(cropLeft, cropEdgeLeft, image, y, b[0]);
  975. }
  976. private void ComputeLeft(Mat cropLeft, Mat cropEdgeLeft, Mat image, int[] y, int border)
  977. {
  978. Ceju ceju = new Ceju();
  979. //获得蓝色,绿色,红色通道图片
  980. Mat[] bgr = Cv2.Split(cropLeft);
  981. Mat imageBlue = bgr[0];
  982. Mat imageGreen = bgr[1];
  983. Mat imageRed = bgr[2];
  984. // 獲得目標區域
  985. Mat imageContour = new Mat();
  986. ceju.GetContour(imageRed, out imageContour);
  987. // 二、计算数据提取区域
  988. int[] dataArea = new int[2];
  989. ceju.GetDataArea(imageContour, out dataArea, "left");
  990. dataArea[1] -= 30;
  991. int middleMianJicaitong = (dataArea[0] + dataArea[1]) / 2;
  992. int middleMiantong = (middleMianJicaitong + dataArea[1]) / 2;
  993. int middleJicaitong = (dataArea[0] + middleMianJicaitong) / 2;
  994. //提取綫條
  995. double ordinateL1 = 0;
  996. ceju.ExtractLines(imageContour, out ordinateL1, dataArea[0], dataArea[1], 1);
  997. double ordinateL3 = 0;
  998. ceju.ExtractLines(imageContour, out ordinateL3, dataArea[0], dataArea[1], ordinateL1, -1);
  999. shangMiantong_Jicaitong.Set(ordinateL3 - ordinateL1, middleMianJicaitong + border, (int)ordinateL1 + y[0], middleMianJicaitong + border, (int)ordinateL3 + y[0]);
  1000. UpdateSuccessLine();
  1001. double ordinateL4 = 0;
  1002. ceju.ExtractLines(imageContour, out ordinateL4, middleJicaitong - 5, middleJicaitong + 5, ordinateL3, 1);
  1003. double ordinateL5 = 0;
  1004. ceju.ExtractLines(imageContour, out ordinateL5, middleJicaitong - 5, middleJicaitong + 5, ordinateL4, -1);
  1005. if (ordinateL5 - ordinateL4 < 40)
  1006. ceju.ExtractLines(imageContour, out ordinateL5, middleJicaitong - 5, middleJicaitong + 5, ordinateL5, -1);
  1007. double ordinateL8 = 0;
  1008. ceju.ExtractLines2(imageContour, out ordinateL8, dataArea[0], dataArea[1], 1);
  1009. double ordinateL6 = 0;
  1010. ceju.ExtractLines2(imageContour, out ordinateL6, dataArea[0], dataArea[1], ordinateL8, -1);
  1011. double ordinateL6Copy = 0;
  1012. ceju.ExtractLines(imageContour, out ordinateL6Copy, middleJicaitong - 5, middleJicaitong + 5, ordinateL5, 1);
  1013. if (ordinateL6Copy < ordinateL6)
  1014. {
  1015. ordinateL6 = ordinateL6Copy;
  1016. }
  1017. xiaMiantong_Jicaitong.Set(ordinateL8 - ordinateL6, middleMianJicaitong + border, (int)ordinateL6 + y[0], middleMianJicaitong + border, (int)ordinateL8 + y[0]);
  1018. UpdateSuccessLine();
  1019. // 提取L2
  1020. double ordinateL2 = 0;
  1021. if (ordinateL1 + 10 < ordinateL3 - 10 && dataArea[0] < dataArea[1])
  1022. {
  1023. ceju.InsideLine(imageGreen, (int)ordinateL1 + 10, (int)ordinateL3 - 10, dataArea[0], dataArea[1], out ordinateL2);
  1024. shangMiantong.Set(ordinateL2 - ordinateL1, middleMiantong + border, (int)ordinateL1 + y[0], middleMiantong + border, (int)ordinateL2 + y[0]);
  1025. shangJicaitong.Set(ordinateL3 - ordinateL2, middleJicaitong + border, (int)ordinateL2 + y[0], middleJicaitong + border, (int)ordinateL3 + y[0]);
  1026. UpdateSuccessLine();
  1027. UpdateSuccessLine();
  1028. }
  1029. // 提取L7
  1030. double ordinateL7 = 0;
  1031. if (ordinateL6 + 10 < ordinateL8 - 10 && dataArea[0] < dataArea[1])
  1032. {
  1033. ceju.InsideLine(imageGreen, (int)ordinateL6 + 10, (int)ordinateL8 - 10, dataArea[0], dataArea[1], out ordinateL7);
  1034. xiaMiantong.Set(ordinateL8 - ordinateL7, middleMiantong + border, (int)ordinateL7 + y[0], middleMiantong + border, (int)ordinateL8 + y[0]);
  1035. xiaJicaitong.Set(ordinateL7 - ordinateL6, middleJicaitong + border, (int)ordinateL6 + y[0], middleJicaitong + border, (int)ordinateL7 + y[0]);
  1036. UpdateSuccessLine();
  1037. UpdateSuccessLine();
  1038. }
  1039. //提取竪綫
  1040. double ordinateV1 = 0;
  1041. ceju.ExtractVerticalLinesR2L(cropEdgeLeft, out ordinateV1, (int)ordinateL3 + 20, (int)ordinateL3 + 40);
  1042. double ordinateV2 = 0;
  1043. ceju.ExtractVerticalLinesR2L(imageContour, out ordinateV2, (int)ordinateL3 + 20, (int)ordinateL3 + 40, ordinateV1);
  1044. shangKongtong.Set(Math.Abs(ordinateV2 - ordinateV1), (int)ordinateV1 + border, (int)ordinateL3 + 30 + y[0], (int)ordinateV2 + border, (int)ordinateL3 + 30 + y[0]);
  1045. UpdateSuccessLine();
  1046. double ordinateV3 = 0;
  1047. ceju.ExtractVerticalLinesR2L(cropEdgeLeft, out ordinateV3, (int)ordinateL6 - 40, (int)ordinateL6 - 20);
  1048. double ordinateV4 = 0;
  1049. ceju.ExtractVerticalLinesR2L(imageContour, out ordinateV4, (int)ordinateL6 - 40, (int)ordinateL6 - 20, ordinateV3);
  1050. xiaKongtong.Set(Math.Abs(ordinateV4 - ordinateV3), (int)ordinateV3 + border, (int)ordinateL6 - 30 + y[0], (int)ordinateV4 + border, (int)ordinateL6 - 30 + y[0]);
  1051. UpdateSuccessLine();
  1052. //計算粗糙度
  1053. int roughness;
  1054. int[] roughnessOrdinate = new int[2];
  1055. ceju.GetSancengRoughness(imageContour, imageRed, (int)ordinateL3, (int)ordinateL4, (int)ordinateL5, (int)ordinateL6,
  1056. (int)ordinateV2, (int)ordinateV4, dataArea, "left", out roughness, out roughnessOrdinate);
  1057. cucaodu.Set(roughness, roughnessOrdinate[0] + border, roughnessOrdinate[1] + y[0], roughnessOrdinate[2] + border, roughnessOrdinate[3] + y[0]);
  1058. UpdateSuccessLine();
  1059. }
  1060. }
  1061. public class SancengbanQuan : AutoMeasureAnalysis
  1062. {
  1063. public DataInfor leftShangJicaitong = new DataInfor();
  1064. public DataInfor leftXiaJicaitong = new DataInfor();
  1065. public DataInfor leftShangMiantong_Jicaitong = new DataInfor();
  1066. public DataInfor leftXiaMiantong_Jicaitong = new DataInfor();
  1067. public DataInfor leftShangMiantong = new DataInfor();
  1068. public DataInfor leftXiaMiantong = new DataInfor();
  1069. public DataInfor leftCucaodu = new DataInfor();
  1070. public DataInfor leftShangKongtong = new DataInfor();
  1071. public DataInfor leftXiaKongtong = new DataInfor();
  1072. public DataInfor rightShangJicaitong = new DataInfor();
  1073. public DataInfor rightXiaJicaitong = new DataInfor();
  1074. public DataInfor rightShangMiantong_Jicaitong = new DataInfor();
  1075. public DataInfor rightXiaMiantong_Jicaitong = new DataInfor();
  1076. public DataInfor rightShangMiantong = new DataInfor();
  1077. public DataInfor rightXiaMiantong = new DataInfor();
  1078. public DataInfor rightCucaodu = new DataInfor();
  1079. public DataInfor rightShangKongtong = new DataInfor();
  1080. public DataInfor rightXiaKongtong = new DataInfor();
  1081. public DataInfor shangKongjing = new DataInfor();
  1082. public DataInfor xiaKongjing = new DataInfor();
  1083. private void Initialize()
  1084. {
  1085. dataInfors = new List<DataInfor>();
  1086. leftShangJicaitong.name = "左側上基材銅";
  1087. leftShangJicaitong.ID = "100114";
  1088. leftShangJicaitong.aliasName = "YNDKLJ";
  1089. leftXiaJicaitong.name = "左側下基材銅";
  1090. leftXiaJicaitong.ID = "100115";
  1091. leftXiaJicaitong.aliasName = "VVTXVV";
  1092. leftShangMiantong_Jicaitong.name = "左側上面銅+基材銅";
  1093. leftShangMiantong_Jicaitong.ID = "100116";
  1094. leftShangMiantong_Jicaitong.aliasName = "ESDAMJ";
  1095. leftXiaMiantong_Jicaitong.name = "左側下面銅+基材銅";
  1096. leftXiaMiantong_Jicaitong.ID = "100117";
  1097. leftXiaMiantong_Jicaitong.aliasName = "XYKOKE";
  1098. leftShangMiantong.name = "左側上面銅";
  1099. leftShangMiantong.ID = "100118";
  1100. leftShangMiantong.aliasName = "GWBGEG";
  1101. leftXiaMiantong.name = "左側下面銅";
  1102. leftXiaMiantong.ID = "100119";
  1103. leftXiaMiantong.aliasName = "AYQHQR";
  1104. leftCucaodu.name = "左側粗糙度";
  1105. leftCucaodu.drawType = "MeasureHLine";
  1106. leftCucaodu.ID = "100120";
  1107. leftCucaodu.aliasName = "QYNTBB";
  1108. leftShangKongtong.name = "左側上孔銅";
  1109. leftShangKongtong.drawType = "MeasureHLine";
  1110. leftShangKongtong.ID = "100121";
  1111. leftShangKongtong.aliasName = "BHKHAE";
  1112. leftXiaKongtong.name = "左側下孔銅";
  1113. leftXiaKongtong.drawType = "MeasureHLine";
  1114. leftXiaKongtong.ID = "100122";
  1115. leftXiaKongtong.aliasName = "BSJUWI";
  1116. rightShangJicaitong.name = "右側上基材銅";
  1117. rightShangJicaitong.ID = "100123";
  1118. rightShangJicaitong.aliasName = "YYTSDH";
  1119. rightXiaJicaitong.name = "右側下基材銅";
  1120. rightXiaJicaitong.ID = "100124";
  1121. rightXiaJicaitong.aliasName = "JCFGSW";
  1122. rightShangMiantong_Jicaitong.name = "右側上面銅+基材銅";
  1123. rightShangMiantong_Jicaitong.ID = "100125";
  1124. rightShangMiantong_Jicaitong.aliasName = "PATOEU";
  1125. rightXiaMiantong_Jicaitong.name = "右側下面銅+基材銅";
  1126. rightXiaMiantong_Jicaitong.ID = "100126";
  1127. rightXiaMiantong_Jicaitong.aliasName = "BODILZ";
  1128. rightShangMiantong.name = "右側上面銅";
  1129. rightShangMiantong.ID = "100127";
  1130. rightShangMiantong.aliasName = "PAWYCE";
  1131. rightXiaMiantong.name = "右側下面銅";
  1132. rightXiaMiantong.ID = "100128";
  1133. rightXiaMiantong.aliasName = "BTSYPM";
  1134. rightCucaodu.name = "右側粗糙度";
  1135. rightCucaodu.drawType = "MeasureHLine";
  1136. rightCucaodu.ID = "100129";
  1137. rightCucaodu.aliasName = "CTHDOR";
  1138. rightShangKongtong.name = "右側上孔銅";
  1139. rightShangKongtong.drawType = "MeasureHLine";
  1140. rightShangKongtong.ID = "100130";
  1141. rightShangKongtong.aliasName = "ZOBMSJ";
  1142. rightXiaKongtong.name = "右側下孔銅";
  1143. rightXiaKongtong.drawType = "MeasureHLine";
  1144. rightXiaKongtong.ID = "100131";
  1145. rightXiaKongtong.aliasName = "MHXLFR";
  1146. shangKongjing.name = "上孔徑";
  1147. shangKongjing.drawType = "MeasureHLine";
  1148. shangKongjing.ID = "100132";
  1149. shangKongjing.aliasName = "YZTKSZ";
  1150. xiaKongjing.name = "下孔徑";
  1151. xiaKongjing.drawType = "MeasureHLine";
  1152. xiaKongjing.ID = "100133";
  1153. xiaKongjing.aliasName = "MHAVDA";
  1154. dataInfors.Add(leftShangJicaitong);
  1155. dataInfors.Add(leftXiaJicaitong);
  1156. dataInfors.Add(leftShangMiantong_Jicaitong);
  1157. dataInfors.Add(leftXiaMiantong_Jicaitong);
  1158. dataInfors.Add(leftShangMiantong);
  1159. dataInfors.Add(leftXiaMiantong);
  1160. dataInfors.Add(leftCucaodu);
  1161. dataInfors.Add(leftShangKongtong);
  1162. dataInfors.Add(leftXiaKongtong);
  1163. dataInfors.Add(rightShangJicaitong);
  1164. dataInfors.Add(rightXiaJicaitong);
  1165. dataInfors.Add(rightShangMiantong_Jicaitong);
  1166. dataInfors.Add(rightXiaMiantong_Jicaitong);
  1167. dataInfors.Add(rightShangMiantong);
  1168. dataInfors.Add(rightXiaMiantong);
  1169. dataInfors.Add(rightCucaodu);
  1170. dataInfors.Add(rightShangKongtong);
  1171. dataInfors.Add(rightXiaKongtong);
  1172. dataInfors.Add(shangKongjing);
  1173. dataInfors.Add(xiaKongjing);
  1174. number = 20;
  1175. success = 0;
  1176. wrongNumber = number;
  1177. }
  1178. public override void Compute(Mat image, bool isCropFlag, int X, int Y)
  1179. {
  1180. Initialize();
  1181. Ceju ceju = new Ceju();
  1182. Mat cropEdge = new Mat();
  1183. int[] y = new int[2];
  1184. int[] b = new int[4];
  1185. ceju.Crop2(image, out cropEdge, out y, out b, isCropFlag);
  1186. Mat cropEdgeLeft = cropEdge[0, cropEdge.Rows - 1, b[0], b[1]];
  1187. Mat cropEdgeRight = cropEdge[0, cropEdge.Rows - 1, b[2], b[3]];
  1188. Mat cropLeft = image[y[0], y[1], b[0], b[1]];
  1189. Mat cropRight = image[y[0], y[1], b[2], b[3]];
  1190. if (isCropFlag)
  1191. {
  1192. y[0] += Y;
  1193. b[0] += X;
  1194. b[2] += X;
  1195. }
  1196. ComputeLeft(cropLeft, cropEdgeLeft, image, y, b[0]);
  1197. ComputeRight(cropRight, cropEdgeRight, image, y, b[2]);
  1198. }
  1199. private void ComputeLeft(Mat cropLeft, Mat cropEdgeLeft, Mat image, int[] y, int border)
  1200. {
  1201. Ceju ceju = new Ceju();
  1202. //获得蓝色,绿色,红色通道图片
  1203. Mat[] bgr = Cv2.Split(cropLeft);
  1204. Mat imageBlue = bgr[0];
  1205. Mat imageGreen = bgr[1];
  1206. Mat imageRed = bgr[2];
  1207. //獲得目標區域
  1208. Mat imageContour = new Mat();
  1209. ceju.GetContour(imageRed, out imageContour);
  1210. // 计算数据提取区域
  1211. int[] dataArea = new int[2];
  1212. ceju.GetDataArea(imageContour, out dataArea, "left");
  1213. dataArea[1] -= 30;
  1214. int middleMianJicaitong = (dataArea[0] + dataArea[1]) / 2;
  1215. int middleMiantong = (middleMianJicaitong + dataArea[1]) / 2;
  1216. int middleJicaitong = (dataArea[0] + middleMianJicaitong) / 2;
  1217. //提取綫條
  1218. double ordinateL1 = 0;
  1219. ceju.ExtractLines(imageContour, out ordinateL1, dataArea[0], dataArea[1], 1);
  1220. double ordinateL3 = 0;
  1221. ceju.ExtractLines(imageContour, out ordinateL3, dataArea[0], dataArea[1], ordinateL1, -1);
  1222. leftShangMiantong_Jicaitong.Set(ordinateL3 - ordinateL1, middleMianJicaitong + border, (int)ordinateL1 + y[0], middleMianJicaitong + border, (int)ordinateL3 + y[0]);
  1223. UpdateSuccessLine();
  1224. double ordinateL4 = 0;
  1225. ceju.ExtractLines(imageContour, out ordinateL4, middleMianJicaitong - 5, middleMianJicaitong + 5, ordinateL3, 1);
  1226. double ordinateL5 = 0;
  1227. ceju.ExtractLines(imageContour, out ordinateL5, middleMianJicaitong - 5, middleMianJicaitong + 5, ordinateL4, -1);
  1228. if (ordinateL5 - ordinateL4 < 40)
  1229. ceju.ExtractLines(imageContour, out ordinateL5, middleMianJicaitong - 5, middleMianJicaitong + 5, ordinateL5, -1);
  1230. double ordinateL8 = 0;
  1231. ceju.ExtractLines2(imageContour, out ordinateL8, dataArea[0], dataArea[1], 1);
  1232. double ordinateL6 = 0;
  1233. ceju.ExtractLines2(imageContour, out ordinateL6, dataArea[0], dataArea[1], ordinateL8, -1);
  1234. double ordinateL6New = 0;
  1235. ceju.ExtractLines(imageContour, out ordinateL6New, dataArea[0], dataArea[1], ordinateL5, 1);
  1236. if (ordinateL6New < ordinateL6)
  1237. ordinateL6 = ordinateL6New;
  1238. leftXiaMiantong_Jicaitong.Set(ordinateL8 - ordinateL6, middleMianJicaitong + border, (int)ordinateL6 + y[0], middleMianJicaitong + border, (int)ordinateL8 + y[0]);
  1239. UpdateSuccessLine();
  1240. // 提取L2
  1241. double ordinateL2 = 0;
  1242. if (ordinateL1 + 10 < ordinateL3 - 10 && dataArea[0] < dataArea[1])
  1243. {
  1244. ceju.InsideLine(imageGreen, (int)ordinateL1 + 10, (int)ordinateL3 - 10, dataArea[0], dataArea[1], out ordinateL2);
  1245. leftShangMiantong.Set(ordinateL2 - ordinateL1, middleMiantong + border, (int)ordinateL1 + y[0], middleMiantong + border, (int)ordinateL2 + y[0]);
  1246. leftShangJicaitong.Set(ordinateL3 - ordinateL2, middleJicaitong + border, (int)ordinateL2 + y[0], middleJicaitong + border, (int)ordinateL3 + y[0]);
  1247. UpdateSuccessLine();
  1248. UpdateSuccessLine();
  1249. }
  1250. // 提取L7
  1251. double ordinateL7 = 0;
  1252. if (ordinateL6 + 10 < ordinateL8 - 10 && dataArea[0] < dataArea[1])
  1253. {
  1254. ceju.InsideLine(imageGreen, (int)ordinateL6 + 10, (int)ordinateL8 - 10, dataArea[0], dataArea[1], out ordinateL7);
  1255. leftXiaMiantong.Set(ordinateL8 - ordinateL7, middleMiantong + border, (int)ordinateL7 + y[0], middleMiantong + border, (int)ordinateL8 + y[0]);
  1256. leftXiaJicaitong.Set(ordinateL7 - ordinateL6, middleJicaitong + border, (int)ordinateL6 + y[0], middleJicaitong + border, (int)ordinateL7 + y[0]);
  1257. UpdateSuccessLine();
  1258. UpdateSuccessLine();
  1259. }
  1260. //提取竪綫
  1261. double ordinateV1 = 0;
  1262. ceju.ExtractVerticalLinesR2L(cropEdgeLeft, out ordinateV1, (int)ordinateL3 + 20, (int)ordinateL3 + 40, 1);
  1263. double ordinateV2 = 0;
  1264. ceju.ExtractVerticalLinesR2L(imageContour, out ordinateV2, (int)ordinateL3 + 20, (int)ordinateL3 + 40, ordinateV1);//, 3);
  1265. //Cv2.ImWrite("", imageContour);
  1266. leftShangKongtong.Set(ordinateV1 - ordinateV2, (int)ordinateV1 + border, (int)ordinateL3 + 30 + y[0], (int)ordinateV2 + border, (int)ordinateL3 + 30 + y[0]);
  1267. shangKongjing.point1 = new System.Drawing.Point((int)ordinateV2 + border, (int)ordinateL1 - 10 + y[0]);
  1268. UpdateSuccessLine();
  1269. double ordinateV3 = 0;
  1270. ceju.ExtractVerticalLinesR2L(cropEdgeLeft, out ordinateV3, (int)ordinateL6 - 40, (int)ordinateL6 - 20, 2);
  1271. double ordinateV4 = 0;
  1272. ceju.ExtractVerticalLinesR2L(imageContour, out ordinateV4, (int)ordinateL6 - 40, (int)ordinateL6 - 20, ordinateV3);//, 4);
  1273. leftXiaKongtong.Set(ordinateV3 - ordinateV4, (int)ordinateV3 + border, (int)ordinateL6 - 30 + y[0], (int)ordinateV4 + border, (int)ordinateL6 - 30 + y[0]);
  1274. xiaKongjing.point1 = new System.Drawing.Point((int)ordinateV4 + border, (int)ordinateL8 + 10 + y[0]);
  1275. UpdateSuccessLine();
  1276. //計算粗糙度
  1277. int roughness = 0;
  1278. int[] roughnessOrdinate = new int[4];
  1279. ceju.GetSancengRoughness(imageContour, imageRed, (int)ordinateL3, (int)ordinateL4, (int)ordinateL5, (int)ordinateL6, (int)ordinateV2, (int)ordinateV4, dataArea, "left", out roughness, out roughnessOrdinate);
  1280. leftCucaodu.Set(roughness, roughnessOrdinate[0] + border, roughnessOrdinate[1] + y[0], roughnessOrdinate[2] + border, roughnessOrdinate[3] + y[0]);
  1281. UpdateSuccessLine();
  1282. }
  1283. private void ComputeRight(Mat cropRight, Mat cropEdgeRight, Mat image, int[] y, int border)
  1284. {
  1285. Ceju ceju = new Ceju();
  1286. //获得蓝色,绿色,红色通道图片
  1287. Mat[] bgr = Cv2.Split(cropRight);
  1288. Mat imageBlue = bgr[0];
  1289. Mat imageGreen = bgr[1];
  1290. Mat imageRed = bgr[2];
  1291. //獲取目標區域
  1292. Mat imageContour = new Mat();
  1293. ceju.GetContour(imageRed, out imageContour);
  1294. // 二、计算数据提取区域
  1295. int[] dataArea = new int[2];
  1296. ceju.GetDataArea(imageContour, out dataArea, "right");
  1297. dataArea[0] += 30;
  1298. //dataArea[1] += 50;
  1299. int middleMianJicaitong = (dataArea[0] + dataArea[1]) / 2;
  1300. int middleMiantong = (middleMianJicaitong + dataArea[1]) / 2;
  1301. int middleJicaitong = (dataArea[0] + middleMianJicaitong) / 2;
  1302. //提取綫條
  1303. double ordinateL1 = 0;
  1304. ceju.ExtractLines(imageContour, out ordinateL1, dataArea[0], dataArea[1], 1);
  1305. double ordinateL3 = 0;
  1306. ceju.ExtractLines(imageContour, out ordinateL3, dataArea[0], dataArea[1], ordinateL1, -1);
  1307. rightShangMiantong_Jicaitong.Set(ordinateL3 - ordinateL1, middleMianJicaitong + border, (int)ordinateL1 + y[0], middleMianJicaitong + border, (int)ordinateL3 + y[0]);
  1308. UpdateSuccessLine();
  1309. double ordinateL4 = 0;
  1310. ceju.ExtractLines(imageContour, out ordinateL4, middleMianJicaitong - 5, middleMianJicaitong + 5, ordinateL3, 1);
  1311. double ordinateL5 = 0;
  1312. ceju.ExtractLines(imageContour, out ordinateL5, middleMianJicaitong - 5, middleMianJicaitong + 5, ordinateL4, -1);
  1313. if (ordinateL5 - ordinateL4 < 40)
  1314. ceju.ExtractLines(imageContour, out ordinateL5, middleMianJicaitong - 5, middleMianJicaitong + 5, ordinateL5, -1);
  1315. double ordinateL8 = 0;
  1316. ceju.ExtractLines2(imageContour, out ordinateL8, dataArea[0], dataArea[1], 1);
  1317. double ordinateL6 = 0;
  1318. ceju.ExtractLines2(imageContour, out ordinateL6, dataArea[0], dataArea[1], ordinateL8, -1);
  1319. double ordinateL6Copy = 0;
  1320. ceju.ExtractLines(imageContour, out ordinateL6Copy, dataArea[0], dataArea[1], ordinateL5, 1);
  1321. if (ordinateL6Copy < ordinateL6)
  1322. ordinateL6 = ordinateL6Copy;
  1323. rightXiaMiantong_Jicaitong.Set(ordinateL8 - ordinateL6, middleMianJicaitong + border, (int)ordinateL6 + y[0], middleMianJicaitong + border, (int)ordinateL8 + y[0]);
  1324. UpdateSuccessLine();
  1325. // 提取L2
  1326. double ordinateL2 = 0;
  1327. if (ordinateL1 + 10 < ordinateL3 - 10 && dataArea[0] < dataArea[1])
  1328. {
  1329. ceju.InsideLine(imageGreen, (int)ordinateL1 + 10, (int)ordinateL3 - 10, dataArea[0], dataArea[1], out ordinateL2);
  1330. rightShangMiantong.Set(ordinateL2 - ordinateL1, middleMiantong + border, (int)ordinateL1 + y[0], middleMiantong + border, (int)ordinateL2 + y[0]);
  1331. rightShangJicaitong.Set(ordinateL3 - ordinateL2, middleJicaitong + border, (int)ordinateL2 + y[0], middleJicaitong + border, (int)ordinateL3 + y[0]);
  1332. UpdateSuccessLine();
  1333. UpdateSuccessLine();
  1334. }
  1335. // 提取L7
  1336. double ordinateL7 = 0;
  1337. if (ordinateL6 + 10 < ordinateL8 - 10 && dataArea[0] < dataArea[1])
  1338. {
  1339. ceju.InsideLine(imageGreen, (int)ordinateL6 + 10, (int)ordinateL8 - 10, dataArea[0], dataArea[1], out ordinateL7);
  1340. rightXiaMiantong.Set(ordinateL8 - ordinateL7, middleMiantong + border, (int)ordinateL7 + y[0], middleMiantong + border, (int)ordinateL8 + y[0]);
  1341. rightXiaJicaitong.Set(ordinateL7 - ordinateL6, middleJicaitong + border, (int)ordinateL6 + y[0], middleJicaitong + border, (int)ordinateL7 + y[0]);
  1342. UpdateSuccessLine();
  1343. UpdateSuccessLine();
  1344. }
  1345. //提取竪綫
  1346. double ordinateV1 = 0;
  1347. ceju.ExtractVerticalLinesL2R(cropEdgeRight, out ordinateV1, (int)ordinateL3 + 20, (int)ordinateL3 + 40, 1);
  1348. double ordinateV2 = 0;
  1349. ceju.ExtractVerticalLinesL2R(imageContour, out ordinateV2, (int)ordinateL3 + 20, (int)ordinateL3 + 40, ordinateV1);
  1350. rightShangKongtong.Set(ordinateV2 - ordinateV1, (int)ordinateV1 + border, (int)ordinateL3 + 30 + y[0], (int)ordinateV2 + border, (int)ordinateL3 + 30 + y[0]);
  1351. shangKongjing.point2 = new System.Drawing.Point((int)ordinateV2 + border, shangKongjing.point1.Y);
  1352. shangKongjing.value = shangKongjing.point2.X - shangKongjing.point1.X;
  1353. UpdateSuccessLine();
  1354. UpdateSuccessLine();
  1355. double ordinateV3 = 0;
  1356. ceju.ExtractVerticalLinesL2R(cropEdgeRight, out ordinateV3, (int)ordinateL6 - 40, (int)ordinateL6 - 20, 2);
  1357. double ordinateV4 = 0;
  1358. ceju.ExtractVerticalLinesL2R(imageContour, out ordinateV4, (int)ordinateL6 - 40, (int)ordinateL6 - 20, ordinateV3);
  1359. rightXiaKongtong.Set(ordinateV4 - ordinateV3, (int)ordinateV3 + border, (int)ordinateL6 - 30 + y[0], (int)ordinateV4 + border, (int)ordinateL6 - 30 + y[0]);
  1360. xiaKongjing.point2 = new System.Drawing.Point((int)ordinateV4 + border, xiaKongjing.point1.Y);
  1361. xiaKongjing.value = xiaKongjing.point2.X - xiaKongjing.point1.X;
  1362. UpdateSuccessLine();
  1363. UpdateSuccessLine();
  1364. //计算粗糙度
  1365. int roughness = 0;
  1366. int[] roughnessOrdinate = new int[4];
  1367. ceju.GetSancengRoughness(imageContour, imageRed, (int)ordinateL3, (int)ordinateL4, (int)ordinateL5, (int)ordinateL6, (int)ordinateV2, (int)ordinateV4, dataArea, "right", out roughness, out roughnessOrdinate);
  1368. rightCucaodu.Set(roughness, roughnessOrdinate[0] + border, roughnessOrdinate[1] + y[0], roughnessOrdinate[2] + border, roughnessOrdinate[3] + y[0]);
  1369. UpdateSuccessLine();
  1370. }
  1371. }
  1372. public class SicengbanYou : AutoMeasureAnalysis
  1373. {
  1374. public DataInfor shangJicaitong = new DataInfor();
  1375. public DataInfor xiaJicaitong = new DataInfor();
  1376. public DataInfor shangMiantong_Jicaitong = new DataInfor();
  1377. public DataInfor xiaMiantong_Jicaitong = new DataInfor();
  1378. public DataInfor shangMiantong = new DataInfor();
  1379. public DataInfor xiaMiantong = new DataInfor();
  1380. public DataInfor shangCucaodu = new DataInfor();
  1381. public DataInfor xiaCucaodu = new DataInfor();
  1382. public DataInfor shangKongtong = new DataInfor();
  1383. public DataInfor zhongKongtong = new DataInfor();
  1384. public DataInfor xiaKongtong = new DataInfor();
  1385. private void Initialize()
  1386. {
  1387. dataInfors = new List<DataInfor>();
  1388. shangJicaitong.name = "上基材銅";
  1389. shangJicaitong.ID = "100079";
  1390. shangJicaitong.aliasName = "SJTBNK";
  1391. xiaJicaitong.name = "下基材銅";
  1392. xiaJicaitong.ID = "100080";
  1393. xiaJicaitong.aliasName = "KVCZGJ";
  1394. shangMiantong_Jicaitong.name = "上面銅+基材銅";
  1395. shangMiantong_Jicaitong.ID = "100081";
  1396. shangMiantong_Jicaitong.aliasName = "FCEGZX";
  1397. xiaMiantong_Jicaitong.name = "下面銅+基材銅";
  1398. xiaMiantong_Jicaitong.ID = "100082";
  1399. xiaMiantong_Jicaitong.aliasName = "OBVYTZ";
  1400. shangMiantong.name = "上面銅";
  1401. shangMiantong.ID = "100083";
  1402. shangMiantong.aliasName = "ENWFZN";
  1403. xiaMiantong.name = "下面銅";
  1404. xiaMiantong.ID = "100084";
  1405. xiaMiantong.aliasName = "SVDPKP";
  1406. shangCucaodu.name = "上粗糙度";
  1407. shangCucaodu.drawType = "MeasureHLine";
  1408. shangCucaodu.ID = "100085";
  1409. shangCucaodu.aliasName = "OQCFTN";
  1410. xiaCucaodu.name = "下粗糙度";
  1411. xiaCucaodu.drawType = "MeasureHLine";
  1412. xiaCucaodu.ID = "100086";
  1413. xiaCucaodu.aliasName = "CJTXBP";
  1414. shangKongtong.name = "上孔銅";
  1415. shangKongtong.drawType = "MeasureHLine";
  1416. shangKongtong.ID = "100087";
  1417. shangKongtong.aliasName = "HFBQJZ";
  1418. zhongKongtong.name = "中孔銅";
  1419. zhongKongtong.drawType = "MeasureHLine";
  1420. zhongKongtong.ID = "100088";
  1421. zhongKongtong.aliasName = "LQDNNH";
  1422. xiaKongtong.name = "下孔銅";
  1423. xiaKongtong.drawType = "MeasureHLine";
  1424. xiaKongtong.ID = "100089";
  1425. xiaKongtong.aliasName = "MMNDTU";
  1426. dataInfors.Add(shangJicaitong);
  1427. dataInfors.Add(xiaJicaitong);
  1428. dataInfors.Add(shangMiantong_Jicaitong);
  1429. dataInfors.Add(xiaMiantong_Jicaitong);
  1430. dataInfors.Add(shangMiantong);
  1431. dataInfors.Add(xiaMiantong);
  1432. dataInfors.Add(shangCucaodu);
  1433. dataInfors.Add(xiaCucaodu);
  1434. dataInfors.Add(shangKongtong);
  1435. dataInfors.Add(zhongKongtong);
  1436. dataInfors.Add(xiaKongtong);
  1437. number = 11;
  1438. success = 0;
  1439. wrongNumber = number;
  1440. }
  1441. public override void Compute(Mat image, bool isCropFlag, int X, int Y)
  1442. {
  1443. Initialize();
  1444. Ceju ceju = new Ceju();
  1445. //获得蓝色,绿色,红色通道图片
  1446. Mat[] bgr = Cv2.Split(image);
  1447. Mat imageBlue = bgr[0];
  1448. Mat imageGreen = bgr[1];
  1449. Mat imageRed = bgr[2];
  1450. // 调色
  1451. Mat sobel = new Mat();
  1452. ceju.Sobel(imageGreen, out sobel);
  1453. Mat se = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(1, 3));
  1454. Mat close = new Mat();
  1455. Cv2.MorphologyEx(sobel, close, MorphTypes.Close, se);
  1456. Mat thresh = close.Threshold(0, 1, ThresholdTypes.Otsu);
  1457. ceju.Fill(thresh, out thresh, 1);
  1458. Mat cropEdge = new Mat();
  1459. int[] y = new int[2];
  1460. int[] b = new int[4];
  1461. ceju.Crop2(image, out cropEdge, out y, out b, isCropFlag);
  1462. Mat cropEdgeRight = thresh[y[0], y[1], b[2], b[3]];//四层边缘图像用新的
  1463. Mat cropRight = image[y[0], y[1], b[2], b[3]];
  1464. if (isCropFlag)
  1465. {
  1466. y[0] += Y;
  1467. b[2] += X;
  1468. }
  1469. ComputeRight(cropRight, cropEdgeRight, image, y, b[2]);
  1470. }
  1471. private void ComputeRight(Mat cropRight, Mat cropEdgeRight, Mat image, int[] y, int border)
  1472. {
  1473. Ceju ceju = new Ceju();
  1474. //获得蓝色,绿色,红色通道图片
  1475. Mat[] bgr = Cv2.Split(cropRight);
  1476. Mat imageBlue = bgr[0];
  1477. Mat imageGreen = bgr[1];
  1478. Mat imageRed = bgr[2];
  1479. //獲取目標區域
  1480. Mat imageContour = new Mat();
  1481. ceju.GetContour(imageRed, out imageContour);
  1482. // 计算数据提取区域
  1483. int[] dataArea = new int[2];
  1484. ceju.GetDataArea(imageContour, out dataArea, "right");
  1485. dataArea[0] += 30;
  1486. //dataArea[1] += 50;
  1487. int middleMianJicaitong = (dataArea[0] + dataArea[1]) / 2;
  1488. int middleMiantong = (middleMianJicaitong + dataArea[1]) / 2;
  1489. int middleJicaitong = (dataArea[0] + middleMianJicaitong) / 2;
  1490. //提取綫條
  1491. double ordinateL1 = 0;
  1492. ceju.ExtractLines(imageContour, out ordinateL1, dataArea[0], dataArea[1], 1);
  1493. double ordinateL3 = 0;
  1494. ceju.ExtractLines(imageContour, out ordinateL3, dataArea[0], dataArea[1], ordinateL1, -1);
  1495. shangMiantong_Jicaitong.Set((int)(ordinateL3 - ordinateL1), middleMianJicaitong + border, (int)ordinateL1 + y[0], middleMianJicaitong + border, (int)ordinateL3 + y[0]);
  1496. UpdateSuccessLine();
  1497. double ordinateL4 = 0;
  1498. ceju.ExtractLines(imageContour, out ordinateL4, middleMiantong - 5, middleMiantong + 5, ordinateL3, 1);
  1499. double ordinateL5 = 0;
  1500. ceju.ExtractLines(imageContour, out ordinateL5, middleMiantong - 5, middleMiantong + 5, ordinateL4, -1);
  1501. if (ordinateL5 - ordinateL4 < 40)
  1502. ceju.ExtractLines(imageContour, out ordinateL5, middleMiantong - 5, middleMiantong + 5, ordinateL5, -1);
  1503. double ordinateL6 = 0;
  1504. ceju.ExtractLines(imageContour, out ordinateL6, middleMiantong - 5, middleMiantong + 5, ordinateL5, 1);
  1505. double ordinateL7 = 0;
  1506. ceju.ExtractLines(imageContour, out ordinateL7, middleMiantong - 5, middleMiantong + 5, ordinateL6, -1);
  1507. double ordinateL10 = 0;
  1508. ceju.ExtractLines2(imageContour, out ordinateL10, dataArea[0], dataArea[1], 1);
  1509. double ordinateL8 = 0;
  1510. ceju.ExtractLines2(imageContour, out ordinateL8, dataArea[0], dataArea[1], ordinateL10, -1);
  1511. double ordinateL8Copy = 0;
  1512. ceju.ExtractLines(imageContour, out ordinateL8Copy, middleMiantong - 5, middleMiantong + 5, ordinateL7, 1);
  1513. if (ordinateL8Copy < ordinateL8)
  1514. ordinateL8 = ordinateL8Copy;
  1515. xiaMiantong_Jicaitong.Set((int)(ordinateL10 - ordinateL8), middleMianJicaitong + border, (int)ordinateL10 + y[0], middleMianJicaitong + border, (int)ordinateL8 + y[0]);
  1516. UpdateSuccessLine();
  1517. // 提取L2
  1518. double ordinateL2 = 0;
  1519. if (ordinateL1 + 10 < ordinateL3 - 10 && dataArea[0] < dataArea[1])
  1520. {
  1521. ceju.InsideLine(imageGreen, (int)ordinateL1 + 10, (int)ordinateL3 - 10, dataArea[0], dataArea[1], out ordinateL2);
  1522. shangMiantong.Set((int)(ordinateL2 - ordinateL1), middleMiantong + border, (int)ordinateL1 + y[0], middleMiantong + border, (int)ordinateL2 + y[0]);
  1523. shangJicaitong.Set((int)(ordinateL3 - ordinateL2), middleJicaitong + border, (int)ordinateL2 + y[0], middleJicaitong + border, (int)ordinateL3 + y[0]);
  1524. UpdateSuccessLine();
  1525. UpdateSuccessLine();
  1526. }
  1527. // 提取L9
  1528. double ordinateL9 = 0;
  1529. if (ordinateL8 + 10 < ordinateL10 - 10 && dataArea[0] < dataArea[1])
  1530. {
  1531. ceju.InsideLine(imageGreen, (int)ordinateL8 + 10, (int)ordinateL10 - 10, dataArea[0], dataArea[1], out ordinateL9);
  1532. xiaMiantong.Set((int)(ordinateL10 - ordinateL9), middleMiantong + border, (int)ordinateL10 + y[0], middleMiantong + border, (int)ordinateL9 + y[0]);
  1533. xiaJicaitong.Set((int)(ordinateL9 - ordinateL8), middleJicaitong + border, (int)ordinateL9 + y[0], middleJicaitong + border, (int)ordinateL8 + y[0]);
  1534. UpdateSuccessLine();
  1535. UpdateSuccessLine();
  1536. }
  1537. //提取竪綫
  1538. double ordinateV1 = 0;
  1539. ceju.ExtractVerticalLinesL2R(cropEdgeRight, out ordinateV1, (int)ordinateL3 + 20, (int)ordinateL3 + 40);
  1540. double ordinateV2 = 0;
  1541. ceju.ExtractVerticalLinesL2R(imageContour, out ordinateV2, (int)ordinateL3 + 20, (int)ordinateL3 + 40, ordinateV1);
  1542. shangKongtong.Set((int)(ordinateV2 - ordinateV1), (int)ordinateV1 + border, (int)ordinateL3 + 30 + y[0], (int)ordinateV2 + border, (int)ordinateL3 + 30 + y[0]);
  1543. UpdateSuccessLine();
  1544. double ordinateV3 = 0;
  1545. ceju.ExtractVerticalLinesL2R(cropEdgeRight, out ordinateV3, (int)ordinateL5 + 20, (int)ordinateL6 - 20);
  1546. double ordinateV4 = 0;
  1547. ceju.ExtractVerticalLinesL2R(imageContour, out ordinateV4, (int)ordinateL5 + 20, (int)ordinateL6 - 20, ordinateV3);
  1548. int middle = (int)(ordinateL5 + ordinateL6) / 2;
  1549. zhongKongtong.Set((int)(ordinateV4 - ordinateV3), (int)ordinateV3 + border, middle + y[0], (int)ordinateV4 + border, middle + y[0]);
  1550. UpdateSuccessLine();
  1551. double ordinateV5 = 0;
  1552. ceju.ExtractVerticalLinesL2R(cropEdgeRight, out ordinateV5, (int)ordinateL8 - 40, (int)ordinateL8 - 20);
  1553. double ordinateV6 = 0;
  1554. ceju.ExtractVerticalLinesL2R(imageContour, out ordinateV6, (int)ordinateL8 - 40, (int)ordinateL8 - 20, ordinateV5);
  1555. xiaKongtong.Set((int)(ordinateV6 - ordinateV5), (int)ordinateV5 + border, (int)ordinateL8 - 30 + y[0], (int)ordinateV6 + border, (int)ordinateL8 - 30 + y[0]);
  1556. UpdateSuccessLine();
  1557. //计算粗糙度
  1558. int shangRoughness = 0, xiaRoughness = 0;
  1559. int[] shangRoughnessOrdinate = new int[4];
  1560. int[] xiaRoughnessOrdinate = new int[4];
  1561. ceju.GetSicengRoughness(imageContour, (int)ordinateL3 + 15, (int)ordinateL4 - 15, (int)ordinateV2, "right", out shangRoughness, out shangRoughnessOrdinate);
  1562. shangCucaodu.Set(shangRoughness, shangRoughnessOrdinate[0] + border, shangRoughnessOrdinate[1] + y[0], shangRoughnessOrdinate[2] + border, shangRoughnessOrdinate[3] + y[0]);
  1563. UpdateSuccessLine();
  1564. ceju.GetSicengRoughness(imageContour, (int)ordinateL7 + 15, (int)ordinateL8 - 15, (int)ordinateV6, "right", out xiaRoughness, out xiaRoughnessOrdinate);
  1565. xiaCucaodu.Set(xiaRoughness, xiaRoughnessOrdinate[0] + border, xiaRoughnessOrdinate[1] + y[0], xiaRoughnessOrdinate[2] + border, xiaRoughnessOrdinate[3] + y[0]);
  1566. UpdateSuccessLine();
  1567. }
  1568. }
  1569. public class SicengbanZuo : AutoMeasureAnalysis
  1570. {
  1571. public DataInfor shangJicaitong = new DataInfor();
  1572. public DataInfor xiaJicaitong = new DataInfor();
  1573. public DataInfor shangMiantong_Jicaitong = new DataInfor();
  1574. public DataInfor xiaMiantong_Jicaitong = new DataInfor();
  1575. public DataInfor shangMiantong = new DataInfor();
  1576. public DataInfor xiaMiantong = new DataInfor();
  1577. public DataInfor shangCucaodu = new DataInfor();
  1578. public DataInfor xiaCucaodu = new DataInfor();
  1579. public DataInfor shangKongtong = new DataInfor();
  1580. public DataInfor zhongKongtong = new DataInfor();
  1581. public DataInfor xiaKongtong = new DataInfor();
  1582. private void Initialize()
  1583. {
  1584. dataInfors = new List<DataInfor>();
  1585. shangJicaitong.name = "上基材銅";
  1586. shangJicaitong.ID = "100067";
  1587. shangJicaitong.aliasName = "TXAKXC";
  1588. xiaJicaitong.name = "下基材銅";
  1589. xiaJicaitong.ID = "100068";
  1590. xiaJicaitong.aliasName = "DLBNQX";
  1591. shangMiantong_Jicaitong.name = "上面銅+基材銅";
  1592. shangMiantong_Jicaitong.ID = "100069";
  1593. shangMiantong_Jicaitong.aliasName = "ZSLKWV";
  1594. xiaMiantong_Jicaitong.name = "下面銅+基材銅";
  1595. xiaMiantong_Jicaitong.ID = "100070";
  1596. xiaMiantong_Jicaitong.aliasName = "NZRVGX";
  1597. shangMiantong.name = "上面銅";
  1598. shangMiantong.ID = "100071";
  1599. shangMiantong.aliasName = "YAXUTY";
  1600. xiaMiantong.name = "下面銅";
  1601. xiaMiantong.ID = "100072";
  1602. xiaMiantong.aliasName = "YSHGYR";
  1603. shangCucaodu.name = "上粗糙度";
  1604. shangCucaodu.ID = "100073";
  1605. shangCucaodu.drawType = "MeasureHLine";
  1606. shangCucaodu.aliasName = "LVOOIZ";
  1607. xiaCucaodu.name = "下粗糙度";
  1608. xiaCucaodu.drawType = "MeasureHLine";
  1609. xiaCucaodu.ID = "100074";
  1610. xiaCucaodu.aliasName = "HGPYBG";
  1611. shangKongtong.name = "上孔銅";
  1612. shangKongtong.drawType = "MeasureHLine";
  1613. shangKongtong.ID = "100075";
  1614. shangKongtong.aliasName = "NPBMEV";
  1615. zhongKongtong.name = "中孔銅";
  1616. zhongKongtong.drawType = "MeasureHLine";
  1617. zhongKongtong.ID = "100076";
  1618. zhongKongtong.aliasName = "ASITOE";
  1619. xiaKongtong.name = "下孔銅";
  1620. xiaKongtong.drawType = "MeasureHLine";
  1621. xiaKongtong.ID = "100077";
  1622. xiaKongtong.aliasName = "DMCGFP";
  1623. dataInfors.Add(shangJicaitong);
  1624. dataInfors.Add(xiaJicaitong);
  1625. dataInfors.Add(shangMiantong_Jicaitong);
  1626. dataInfors.Add(xiaMiantong_Jicaitong);
  1627. dataInfors.Add(shangMiantong);
  1628. dataInfors.Add(xiaMiantong);
  1629. dataInfors.Add(shangCucaodu);
  1630. dataInfors.Add(xiaCucaodu);
  1631. dataInfors.Add(shangKongtong);
  1632. dataInfors.Add(zhongKongtong);
  1633. dataInfors.Add(xiaKongtong);
  1634. number = 11;
  1635. success = 0;
  1636. wrongNumber = number;
  1637. }
  1638. public override void Compute(Mat image, bool isCropFlag, int X, int Y)
  1639. {
  1640. Initialize();
  1641. Ceju ceju = new Ceju();
  1642. //获得蓝色,绿色,红色通道图片
  1643. Mat[] bgr = Cv2.Split(image);
  1644. Mat imageBlue = bgr[0];
  1645. Mat imageGreen = bgr[1];
  1646. Mat imageRed = bgr[2];
  1647. // 调色
  1648. Mat sobel = new Mat();
  1649. ceju.Sobel(imageGreen, out sobel);
  1650. Mat se = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(1, 3));
  1651. Mat close = new Mat();
  1652. Cv2.MorphologyEx(sobel, close, MorphTypes.Close, se);
  1653. Mat thresh = close.Threshold(0, 1, ThresholdTypes.Otsu);
  1654. ceju.Fill(thresh, out thresh, 1);
  1655. Mat cropEdge = new Mat();
  1656. int[] y = new int[2];
  1657. int[] b = new int[4];
  1658. ceju.Crop2(image, out cropEdge, out y, out b, isCropFlag);
  1659. Mat cropEdgeLeft = thresh[y[0], y[1], b[0], b[1]];//四层边缘图像用新的
  1660. Mat cropLeft = image[y[0], y[1], b[0], b[1]];
  1661. if (isCropFlag)
  1662. {
  1663. y[0] += Y;
  1664. b[0] += X;
  1665. }
  1666. ComputeLeft(cropLeft, cropEdgeLeft, image, y, b[0]);
  1667. }
  1668. private void ComputeLeft(Mat cropLeft, Mat cropEdgeLeft, Mat image, int[] y, int border)
  1669. {
  1670. Ceju ceju = new Ceju();
  1671. //获得蓝色,绿色,红色通道图片
  1672. Mat[] bgr = Cv2.Split(cropLeft);
  1673. Mat imageBlue = bgr[0];
  1674. Mat imageGreen = bgr[1];
  1675. Mat imageRed = bgr[2];
  1676. // 獲得目標區域
  1677. Mat imageContour = new Mat();
  1678. ceju.GetContour(imageRed, out imageContour);
  1679. // 计算数据提取区域
  1680. int[] dataArea = new int[2];
  1681. ceju.GetDataArea(imageContour, out dataArea, "left");
  1682. dataArea[1] -= 70;
  1683. if (dataArea[1] - dataArea[0] < 20)
  1684. dataArea[0] -= 70;
  1685. int middleMianJicaitong = (dataArea[0] + dataArea[1]) / 2;
  1686. int middleMiantong = (middleMianJicaitong + dataArea[1]) / 2;
  1687. int middleJicaitong = (dataArea[0] + middleMianJicaitong) / 2;
  1688. //提取綫條
  1689. double ordinateL1 = 0;
  1690. ceju.ExtractLines(imageContour, out ordinateL1, dataArea[0], dataArea[1], 1);
  1691. double ordinateL3 = 0;
  1692. ceju.ExtractLines(imageContour, out ordinateL3, dataArea[0], dataArea[1], ordinateL1, -1);
  1693. shangMiantong_Jicaitong.Set((int)(ordinateL3 - ordinateL1), middleMianJicaitong + border, (int)ordinateL1 + y[0], middleMianJicaitong + border, (int)ordinateL3 + y[0]);
  1694. UpdateSuccessLine();
  1695. double ordinateL4 = 0;
  1696. ceju.ExtractLines(imageContour, out ordinateL4, middleJicaitong - 15, middleJicaitong - 5, ordinateL3, 1);
  1697. double ordinateL5 = 0;
  1698. ceju.ExtractLines(imageContour, out ordinateL5, middleJicaitong - 15, middleJicaitong - 5, ordinateL4, -1);
  1699. if (ordinateL5 - ordinateL4 < 40)
  1700. ceju.ExtractLines(imageContour, out ordinateL5, middleJicaitong - 15, middleJicaitong - 5, ordinateL5, -1);
  1701. double ordinateL6 = 0;
  1702. ceju.ExtractLines(imageContour, out ordinateL6, middleJicaitong - 15, middleJicaitong - 5, ordinateL5, 1);
  1703. double ordinateL7 = 0;
  1704. ceju.ExtractLines(imageContour, out ordinateL7, middleJicaitong - 15, middleJicaitong - 5, ordinateL6, -1);
  1705. double ordinateL10 = 0;
  1706. ceju.ExtractLines2(imageContour, out ordinateL10, dataArea[0], dataArea[1], 1);
  1707. double ordinateL8 = 0;
  1708. ceju.ExtractLines2(imageContour, out ordinateL8, dataArea[0], dataArea[1], ordinateL10, -1);
  1709. double ordinateL8Copy = 0;
  1710. ceju.ExtractLines(imageContour, out ordinateL8Copy, middleJicaitong - 15, middleJicaitong - 5, ordinateL7, 1);
  1711. if (ordinateL8Copy < ordinateL8)
  1712. ordinateL8 = ordinateL8Copy;
  1713. xiaMiantong_Jicaitong.Set((int)(ordinateL10 - ordinateL8), middleMianJicaitong + border, (int)ordinateL10 + y[0], middleMianJicaitong + border, (int)ordinateL8 + y[0]);
  1714. UpdateSuccessLine();
  1715. // 提取L2
  1716. double ordinateL2 = 0;
  1717. if (ordinateL1 + 10 < ordinateL3 - 10 && dataArea[0] < dataArea[1])
  1718. {
  1719. ceju.InsideLine(imageGreen, (int)ordinateL1 + 10, (int)ordinateL3 - 10, dataArea[0], dataArea[1], out ordinateL2);
  1720. shangMiantong.Set((int)(ordinateL2 - ordinateL1), middleMiantong + border, (int)ordinateL1 + y[0], middleMiantong + border, (int)ordinateL2 + y[0]);
  1721. shangJicaitong.Set((int)(ordinateL3 - ordinateL2), middleJicaitong + border, (int)ordinateL2 + y[0], middleJicaitong + border, (int)ordinateL3 + y[0]);
  1722. UpdateSuccessLine();
  1723. UpdateSuccessLine();
  1724. }
  1725. // 提取L9
  1726. double ordinateL9 = 0;
  1727. if (ordinateL8 + 10 < ordinateL10 - 10 && dataArea[0] < dataArea[1])
  1728. {
  1729. ceju.InsideLine(imageGreen, (int)ordinateL8 + 10, (int)ordinateL10 - 10, dataArea[0], dataArea[1], out ordinateL9);
  1730. xiaMiantong.Set((int)(ordinateL10 - ordinateL9), middleMiantong + border, (int)ordinateL10 + y[0], middleMiantong + border, (int)ordinateL9 + y[0]);
  1731. xiaJicaitong.Set((int)(ordinateL9 - ordinateL8), middleJicaitong + border, (int)ordinateL9 + y[0], middleJicaitong + border, (int)ordinateL8 + y[0]);
  1732. UpdateSuccessLine();
  1733. UpdateSuccessLine();
  1734. }
  1735. //提取竪綫
  1736. double ordinateV1 = 0;
  1737. ceju.ExtractVerticalLinesR2L(cropEdgeLeft, out ordinateV1, (int)ordinateL3 + 20, (int)ordinateL3 + 40);
  1738. double ordinateV2 = 0;
  1739. ceju.ExtractVerticalLinesR2L(imageContour, out ordinateV2, (int)ordinateL3 + 20, (int)ordinateL3 + 40, ordinateV1);
  1740. shangKongtong.Set((int)Math.Abs(ordinateV2 - ordinateV1), (int)ordinateV1 + border, (int)ordinateL3 + 30 + y[0], (int)ordinateV2 + border, (int)ordinateL3 + 30 + y[0]);
  1741. UpdateSuccessLine();
  1742. double ordinateV3 = 0;
  1743. ceju.ExtractVerticalLinesR2L(cropEdgeLeft, out ordinateV3, (int)ordinateL6 - 40, (int)ordinateL6 - 20);
  1744. double ordinateV4 = 0;
  1745. ceju.ExtractVerticalLinesR2L(imageContour, out ordinateV4, (int)ordinateL6 - 40, (int)ordinateL6 - 20, ordinateV3);
  1746. int middle = (int)(ordinateL5 + ordinateL6) / 2;
  1747. zhongKongtong.Set((int)Math.Abs(ordinateV4 - ordinateV3), (int)ordinateV3 + border, (int)ordinateL6 - 30 + y[0], (int)ordinateV4 + border, (int)ordinateL6 - 30 + y[0]);
  1748. UpdateSuccessLine();
  1749. double ordinateV5 = 0;
  1750. ceju.ExtractVerticalLinesR2L(cropEdgeLeft, out ordinateV5, (int)ordinateL8 - 40, (int)ordinateL8 - 20);
  1751. double ordinateV6 = 0;
  1752. ceju.ExtractVerticalLinesR2L(imageContour, out ordinateV6, (int)ordinateL8 - 40, (int)ordinateL8 - 20, ordinateV5);
  1753. xiaKongtong.Set((int)Math.Abs(ordinateV6 - ordinateV5), (int)ordinateV5 + border, (int)ordinateL8 - 30 + y[0], (int)ordinateV6 + border, (int)ordinateL8 - 30 + y[0]);
  1754. UpdateSuccessLine();
  1755. //计算粗糙度
  1756. int shangRoughness = 0, xiaRoughness = 0;
  1757. int[] shangRoughnessOrdinate = new int[4];
  1758. int[] xiaRoughnessOrdinate = new int[4];
  1759. ceju.GetSicengRoughness(imageContour, (int)ordinateL3 + 15, (int)ordinateL4 - 15, (int)ordinateV2, "left", out shangRoughness, out shangRoughnessOrdinate);
  1760. shangCucaodu.Set(shangRoughness, shangRoughnessOrdinate[0] + border, shangRoughnessOrdinate[1] + y[0], shangRoughnessOrdinate[2] + border, shangRoughnessOrdinate[3] + y[0]);
  1761. UpdateSuccessLine();
  1762. ceju.GetSicengRoughness(imageContour, (int)ordinateL7 + 15, (int)ordinateL8 - 15, (int)ordinateV6, "left", out xiaRoughness, out xiaRoughnessOrdinate);
  1763. xiaCucaodu.Set(xiaRoughness, xiaRoughnessOrdinate[0] + border, xiaRoughnessOrdinate[1] + y[0], xiaRoughnessOrdinate[2] + border, xiaRoughnessOrdinate[3] + y[0]);
  1764. UpdateSuccessLine();
  1765. }
  1766. }
  1767. public class SicengbanKongjing : AutoMeasureAnalysis
  1768. {
  1769. public DataInfor shangKongjing = new DataInfor();
  1770. public DataInfor xiaKongjing = new DataInfor();
  1771. public void Initialize()
  1772. {
  1773. dataInfors = new List<DataInfor>();
  1774. shangKongjing.name = "上孔徑";
  1775. shangKongjing.drawType = "MeasureHLine";
  1776. shangKongjing.ID = "100091";
  1777. shangKongjing.aliasName = "OQWENM";
  1778. xiaKongjing.name = "下孔徑";
  1779. xiaKongjing.drawType = "MeasureHLine";
  1780. xiaKongjing.ID = "100092";
  1781. xiaKongjing.aliasName = "BUDLXU";
  1782. dataInfors.Add(shangKongjing);
  1783. dataInfors.Add(xiaKongjing);
  1784. success = 0;
  1785. number = 2;
  1786. wrongNumber = number;
  1787. }
  1788. public override void Compute(Mat image, bool isCropFlag, int X, int Y)
  1789. {
  1790. Initialize();
  1791. Ceju ceju = new Ceju();
  1792. Mat[] bgr = Cv2.Split(image);
  1793. Mat imageBlue = bgr[0];
  1794. Mat imageGreen = bgr[1];
  1795. Mat imageRed = bgr[2];
  1796. // 调色
  1797. Mat sobel = new Mat();
  1798. ceju.Sobel(imageGreen, out sobel);
  1799. Mat se = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(1, 3));
  1800. Mat close = new Mat();
  1801. Cv2.MorphologyEx(sobel, close, MorphTypes.Close, se);
  1802. Mat thresh = close.Threshold(0, 1, ThresholdTypes.Otsu);
  1803. ceju.Fill(thresh, out thresh, 1);
  1804. Mat cropEdge = new Mat();
  1805. int[] y = new int[2];
  1806. int[] b = new int[4];
  1807. ceju.CropSicengKongjing(image, out cropEdge, out y, out b, isCropFlag);
  1808. Mat cropEdgeLeft = thresh[y[0], y[1], b[0], b[1]];
  1809. Mat cropEdgeRight = thresh[y[0], y[1], b[2], b[3]];//四层边缘图像用新的
  1810. Mat cropLeft = image[y[0], y[1], b[0], b[1]];
  1811. Mat cropRight = image[y[0], y[1], b[2], b[3]];
  1812. if (isCropFlag)
  1813. {
  1814. y[0] += Y;
  1815. b[0] += X;
  1816. b[2] += X;
  1817. }
  1818. ComputeLeft(cropLeft, cropEdgeLeft, image, y, b[0]);
  1819. ComputeRight(cropRight, cropEdgeRight, image, y, b[2]);
  1820. }
  1821. private void ComputeLeft(Mat cropLeft, Mat cropEdgeLeft, Mat image, int[] y, int border)
  1822. {
  1823. Ceju ceju = new Ceju();
  1824. //获得蓝色,绿色,红色通道图片
  1825. Mat[] bgr = Cv2.Split(cropLeft);
  1826. Mat imageBlue = bgr[0];
  1827. Mat imageGreen = bgr[1];
  1828. Mat imageRed = bgr[2];
  1829. //獲取目標區域
  1830. Mat imageContour = new Mat();
  1831. ceju.GetContour(imageRed, out imageContour);
  1832. // 二、计算数据提取区域
  1833. int[] dataArea = new int[2];
  1834. ceju.GetDataArea(imageContour, out dataArea, "left");
  1835. dataArea[1] -= 70;
  1836. dataArea[0] -= 70;
  1837. int middleMianJicaitong = (dataArea[0] + dataArea[1]) / 2;
  1838. int middleMiantong = (middleMianJicaitong + dataArea[1]) / 2;
  1839. int middleJicaitong = (dataArea[0] + middleMianJicaitong) / 2;
  1840. //提取綫條
  1841. double ordinateL1 = 0;
  1842. ceju.ExtractLines(imageContour, out ordinateL1, dataArea[0], dataArea[1], 1);
  1843. double ordinateL3 = 0;
  1844. ceju.ExtractLines(imageContour, out ordinateL3, dataArea[0], dataArea[1], ordinateL1, -1);
  1845. double ordinateL4 = 0;
  1846. ceju.ExtractLines(imageContour, out ordinateL4, middleJicaitong - 15, middleJicaitong - 5, ordinateL3, 1);
  1847. double ordinateL5 = 0;
  1848. ceju.ExtractLines(imageContour, out ordinateL5, middleJicaitong - 15, middleJicaitong - 5, ordinateL4, -1);
  1849. if (ordinateL5 - ordinateL4 < 40)
  1850. ceju.ExtractLines(imageContour, out ordinateL5, middleJicaitong - 15, middleJicaitong - 5, ordinateL5, -1);
  1851. double ordinateL6 = 0;
  1852. ceju.ExtractLines(imageContour, out ordinateL6, middleJicaitong - 15, middleJicaitong - 5, ordinateL5, 1);
  1853. double ordinateL7 = 0;
  1854. ceju.ExtractLines(imageContour, out ordinateL7, middleJicaitong - 15, middleJicaitong - 5, ordinateL6, -1);
  1855. double ordinateL10 = 0;
  1856. ceju.ExtractLines2(imageContour, out ordinateL10, dataArea[0], dataArea[1], 1);
  1857. double ordinateL8 = 0;
  1858. ceju.ExtractLines2(imageContour, out ordinateL8, dataArea[0], dataArea[1], ordinateL10, -1);
  1859. double ordinateL8Copy = 0;
  1860. ceju.ExtractLines(imageContour, out ordinateL8Copy, middleJicaitong - 15, middleJicaitong - 5, ordinateL7, 1);
  1861. if (ordinateL8Copy < ordinateL8)
  1862. ordinateL8 = ordinateL8Copy;
  1863. //提取竪綫
  1864. double ordinateV1 = 0;
  1865. ceju.ExtractVerticalLinesR2L(cropEdgeLeft, out ordinateV1, (int)ordinateL3 + 20, (int)ordinateL3 + 40);
  1866. double ordinateV2 = 0;
  1867. ceju.ExtractVerticalLinesR2L(imageContour, out ordinateV2, (int)ordinateL3 + 20, (int)ordinateL3 + 40, ordinateV1);
  1868. shangKongjing.point1 = new System.Drawing.Point((int)ordinateV2 + border, (int)ordinateL1 - 10 + y[0]);
  1869. double ordinateV5 = 0;
  1870. ceju.ExtractVerticalLinesR2L(cropEdgeLeft, out ordinateV5, (int)ordinateL8 - 40, (int)ordinateL8 - 20);
  1871. double ordinateV6 = 0;
  1872. ceju.ExtractVerticalLinesR2L(imageContour, out ordinateV6, (int)ordinateL8 - 40, (int)ordinateL8 - 20, ordinateV5);
  1873. xiaKongjing.point1 = new System.Drawing.Point((int)ordinateV6 + border, (int)ordinateL10 + 10 + y[0]);
  1874. }
  1875. private void ComputeRight(Mat cropRight, Mat cropEdgeRight, Mat image, int[] y, int border)
  1876. {
  1877. Ceju ceju = new Ceju();
  1878. //获得蓝色,绿色,红色通道图片
  1879. Mat[] bgr = Cv2.Split(cropRight);
  1880. Mat imageBlue = bgr[0];
  1881. Mat imageGreen = bgr[1];
  1882. Mat imageRed = bgr[2];
  1883. //獲取目標區域
  1884. Mat imageContour = new Mat();
  1885. ceju.GetContour(imageRed, out imageContour);
  1886. // 二、计算数据提取区域
  1887. int[] dataArea = new int[2];
  1888. ceju.GetDataArea(imageContour, out dataArea, "right");
  1889. dataArea[0] += 30;
  1890. //dataArea[1] += 50;
  1891. int middleMianJicaitong = (dataArea[0] + dataArea[1]) / 2;
  1892. int middleMiantong = (middleMianJicaitong + dataArea[1]) / 2;
  1893. int middleJicaitong = (dataArea[0] + middleMianJicaitong) / 2;
  1894. //提取綫條
  1895. double ordinateL1 = 0;
  1896. ceju.ExtractLines(imageContour, out ordinateL1, dataArea[0], dataArea[1], 1);
  1897. double ordinateL3 = 0;
  1898. ceju.ExtractLines(imageContour, out ordinateL3, dataArea[0], dataArea[1], ordinateL1, -1);
  1899. double ordinateL4 = 0;
  1900. ceju.ExtractLines(imageContour, out ordinateL4, middleMiantong + 5, middleMiantong + 15, ordinateL3, 1);
  1901. double ordinateL5 = 0;
  1902. ceju.ExtractLines(imageContour, out ordinateL5, middleMiantong + 5, middleMiantong + 15, ordinateL4, -1);
  1903. if (ordinateL5 - ordinateL4 < 40)
  1904. ceju.ExtractLines(imageContour, out ordinateL5, middleMiantong + 5, middleMiantong + 15, ordinateL5, -1);
  1905. double ordinateL6 = 0;
  1906. ceju.ExtractLines(imageContour, out ordinateL6, middleMiantong + 5, middleMiantong + 15, ordinateL5, 1);
  1907. double ordinateL7 = 0;
  1908. ceju.ExtractLines(imageContour, out ordinateL7, middleMiantong + 5, middleMiantong + 15, ordinateL6, -1);
  1909. double ordinateL10 = 0;
  1910. ceju.ExtractLines2(imageContour, out ordinateL10, dataArea[0], dataArea[1], 1);
  1911. double ordinateL8 = 0;
  1912. ceju.ExtractLines2(imageContour, out ordinateL8, dataArea[0], dataArea[1], ordinateL10, -1);
  1913. double ordinateL8Copy = 0;
  1914. ceju.ExtractLines(imageContour, out ordinateL8Copy, middleMiantong + 5, middleMiantong + 15, ordinateL7, 1);
  1915. if (ordinateL8Copy < ordinateL8)
  1916. ordinateL8 = ordinateL8Copy;
  1917. //提取竪綫
  1918. double ordinateV1 = 0;
  1919. ceju.ExtractVerticalLinesL2R(cropEdgeRight, out ordinateV1, (int)ordinateL3 + 20, (int)ordinateL3 + 40);
  1920. double ordinateV2 = 0;
  1921. ceju.ExtractVerticalLinesL2R(imageContour, out ordinateV2, (int)ordinateL3 + 20, (int)ordinateL3 + 40, ordinateV1);
  1922. shangKongjing.point2 = new System.Drawing.Point((int)ordinateV2 + border, shangKongjing.point1.Y);
  1923. shangKongjing.value = shangKongjing.point2.X - shangKongjing.point1.X;
  1924. UpdateSuccessLine();
  1925. double ordinateV5 = 0;
  1926. ceju.ExtractVerticalLinesL2R(cropEdgeRight, out ordinateV5, (int)ordinateL8 - 40, (int)ordinateL8 - 20);
  1927. double ordinateV6 = 0;
  1928. ceju.ExtractVerticalLinesL2R(imageContour, out ordinateV6, (int)ordinateL8 - 40, (int)ordinateL8 - 20, ordinateV5);
  1929. xiaKongjing.point2 = new System.Drawing.Point((int)ordinateV6 + border, xiaKongjing.point1.Y);
  1930. xiaKongjing.value = xiaKongjing.point2.X - xiaKongjing.point1.X;
  1931. UpdateSuccessLine();
  1932. }
  1933. }
  1934. public class Qianmangkong : AutoMeasureAnalysis
  1935. {
  1936. public DataInfor leftJicaitong = new DataInfor();
  1937. public DataInfor rightJicaitong = new DataInfor();
  1938. public DataInfor leftMiantong_Jicaitong = new DataInfor();
  1939. public DataInfor rightMiantong_Jicaitong = new DataInfor();
  1940. public DataInfor leftMiantong = new DataInfor();
  1941. public DataInfor rightMiantong = new DataInfor();
  1942. public DataInfor leftKongtong = new DataInfor();
  1943. public DataInfor rightKongtong = new DataInfor();
  1944. public DataInfor shangKongjing = new DataInfor();
  1945. public DataInfor xiaKongjing = new DataInfor();
  1946. public DataInfor kongdi = new DataInfor();
  1947. public DataInfor kongdiyaoshiliang = new DataInfor();
  1948. public DataInfor leftMinimumRing = new DataInfor();
  1949. public DataInfor rightMinimumRing = new DataInfor();
  1950. private void Initialize()
  1951. {
  1952. dataInfors = new List<DataInfor>();
  1953. leftJicaitong.name = "左基材銅";
  1954. leftJicaitong.ID = "100001";
  1955. leftJicaitong.aliasName = "SVLUXI";
  1956. rightJicaitong.name = "右基材銅";
  1957. rightJicaitong.ID = "100002";
  1958. rightJicaitong.aliasName = "FDHENG";
  1959. leftMiantong_Jicaitong.name = "左面銅+基材銅";
  1960. leftMiantong_Jicaitong.ID = "100003";
  1961. leftMiantong_Jicaitong.aliasName = "GSFVKE";
  1962. rightMiantong_Jicaitong.name = "右面銅+基材銅";
  1963. rightMiantong_Jicaitong.ID = "100004";
  1964. rightMiantong_Jicaitong.aliasName = "EOZDNW";
  1965. leftMiantong.name = "左面銅";
  1966. leftMiantong.ID = "100005";
  1967. leftMiantong.aliasName = "EOOIMB";
  1968. rightMiantong.name = "右面銅";
  1969. rightMiantong.ID = "100006";
  1970. rightMiantong.aliasName = "DSUAYP";
  1971. leftKongtong.name = "左孔銅";
  1972. leftKongtong.drawType = "MeasureLine";
  1973. leftKongtong.ID = "100007";
  1974. leftKongtong.aliasName = "DTIFWU";
  1975. rightKongtong.name = "右孔銅";
  1976. rightKongtong.drawType = "MeasureLine";
  1977. rightKongtong.ID = "100008";
  1978. rightKongtong.aliasName = "XFNVKM";
  1979. shangKongjing.name = "上孔徑";
  1980. shangKongjing.drawType = "MeasureHLine";
  1981. shangKongjing.ID = "100009";
  1982. shangKongjing.aliasName = "FIWASX";
  1983. xiaKongjing.name = "下孔徑";
  1984. xiaKongjing.drawType = "MeasureHLine";
  1985. xiaKongjing.ID = "100010";
  1986. xiaKongjing.aliasName = "QLIOHM";
  1987. kongdi.name = "孔底";
  1988. kongdi.ID = "100011";
  1989. kongdi.aliasName = "YVOVEU";
  1990. kongdiyaoshiliang.name = "孔底咬蝕量";
  1991. kongdiyaoshiliang.ID = "100012";
  1992. kongdiyaoshiliang.aliasName = "IAZJJN";
  1993. leftMinimumRing.name = "左孔環";
  1994. leftMinimumRing.ID = "200001";
  1995. leftMinimumRing.aliasName = "VKRGES";
  1996. leftMinimumRing.drawType = "MeasureHLine";
  1997. rightMinimumRing.name = "右孔環";
  1998. rightMinimumRing.ID = "200002";
  1999. rightMinimumRing.aliasName = "XOLSKM";
  2000. rightMinimumRing.drawType = "MeasureHLine";
  2001. dataInfors.Add(leftJicaitong);
  2002. dataInfors.Add(rightJicaitong);
  2003. dataInfors.Add(leftMiantong_Jicaitong);
  2004. dataInfors.Add(rightMiantong_Jicaitong);
  2005. dataInfors.Add(leftMiantong);
  2006. dataInfors.Add(rightMiantong);
  2007. dataInfors.Add(leftKongtong);
  2008. dataInfors.Add(rightKongtong);
  2009. dataInfors.Add(shangKongjing);
  2010. dataInfors.Add(xiaKongjing);
  2011. dataInfors.Add(kongdi);
  2012. dataInfors.Add(kongdiyaoshiliang);
  2013. dataInfors.Add(leftMinimumRing);
  2014. dataInfors.Add(rightMinimumRing);
  2015. success = 0;
  2016. number = 16;
  2017. wrongNumber = number;
  2018. }
  2019. public override void Compute(Mat image, bool isCropFlag, int X, int Y)
  2020. {
  2021. Initialize();
  2022. Ceju ceju = new Ceju();
  2023. //避免旋轉白邊的裁剪
  2024. int border = 0;
  2025. int upper = 0;
  2026. if (!isCropFlag)
  2027. {
  2028. int range = 0;
  2029. ceju.CropBothSide(image, out image, out range);
  2030. border += range;
  2031. upper += range;
  2032. }
  2033. // 一、预处理
  2034. DateTime t = DateTime.Now;
  2035. //获得蓝色,绿色,红色通道图片
  2036. Mat[] bgr = Cv2.Split(image);
  2037. Mat imageBlue = bgr[0];
  2038. Mat imageGreen = bgr[1];
  2039. Mat imageRed = bgr[2];
  2040. //獲得目標區域
  2041. Mat imageContour = new Mat();
  2042. ceju.GetContour(imageRed, out imageContour);
  2043. //Cv2.ImWrite(@"C:\Users\54434\Desktop\imageContour.jpg", imageContour * 255);
  2044. //裁剪
  2045. int[] y = new int[2];
  2046. Mat cropContour = new Mat();
  2047. ceju.Crop(imageContour, out y, out cropContour, isCropFlag);
  2048. Mat cropContourOrigin = image[y[0], y[1], 0, image.Cols - 1];
  2049. //ceju.ImageShow(cropContour*255);
  2050. //Cv2.ImWrite(@"C:\Users\54434\Desktop\2.jpg", cropContour * 255);
  2051. upper += y[0];
  2052. if (isCropFlag)
  2053. {
  2054. upper += Y;
  2055. border = X;
  2056. }
  2057. //计算提取区域
  2058. int[] dataArea = new int[4];
  2059. ceju.GetMangkongDataAreaForQian(cropContour, out dataArea);
  2060. dataArea[1] -= 20;
  2061. dataArea[2] += 20;
  2062. int leftMiddleMianJicaitong = (dataArea[0] + dataArea[1]) / 2;
  2063. int leftMiddleMiantong = (leftMiddleMianJicaitong + dataArea[1]) / 2;
  2064. int leftMiddleJicaitong = (dataArea[0] + leftMiddleMianJicaitong) / 2;
  2065. int rightMiddleMianJicaitong = (dataArea[2] + dataArea[3]) / 2;
  2066. int rightMiddleMiantong = (rightMiddleMianJicaitong + dataArea[3]) / 2;
  2067. int rightMiddleJicaitong = (dataArea[2] + rightMiddleMianJicaitong) / 2;
  2068. //计算横线高度
  2069. double leftOrdinateMiantong = 0;
  2070. //Cv2.ImWrite(@"C:\Users\54434\Desktop\cropContour.jpg", cropContour * 255);
  2071. ceju.ExtractLines(cropContour, out leftOrdinateMiantong, leftMiddleMiantong - 5, leftMiddleMiantong + 5, 1);
  2072. double leftOrdinateMian_Jicaitong = 0;
  2073. ceju.ExtractLines(cropContour, out leftOrdinateMian_Jicaitong, leftMiddleMianJicaitong - 5, leftMiddleMianJicaitong + 5, 1);
  2074. double leftOrdinate1 = (leftOrdinateMiantong + leftOrdinateMian_Jicaitong) / 2;
  2075. //ceju.LineShow(image, new Point(dataArea[0], leftOrdinate1 + y[0]), new Point(dataArea[1], 150 + y[0]));
  2076. //ceju.ImageShow(image);
  2077. double leftOrdinate3 = 0;
  2078. ceju.ExtractLines(cropContour, out leftOrdinate3, dataArea[0], dataArea[1], leftOrdinate1, -1);
  2079. leftMiantong_Jicaitong.Set(leftOrdinate3 - leftOrdinateMian_Jicaitong, leftMiddleMianJicaitong + border, (int)leftOrdinateMian_Jicaitong + upper, leftMiddleMianJicaitong + border, (int)leftOrdinate3 + upper);
  2080. UpdateSuccessLine();
  2081. double leftOrdinate4 = 0;
  2082. ceju.ExtractLines(cropContour, out leftOrdinate4, dataArea[0], dataArea[1], leftOrdinate3, 1);
  2083. double leftOrdinate5 = 0;
  2084. ceju.ExtractLines2(cropContour, out leftOrdinate5, dataArea[0], dataArea[1], cropContour.Rows - 1, 1);
  2085. double leftOrdinate4Copy = 0;
  2086. ceju.ExtractLines2(cropContour, out leftOrdinate4Copy, leftMiddleMianJicaitong - 5, leftMiddleMianJicaitong + 5, leftOrdinate5, -1);
  2087. if (leftOrdinate4Copy < leftOrdinate4 && leftOrdinate4Copy > 0)
  2088. leftOrdinate4 = leftOrdinate4Copy;
  2089. double rightOrdinateMiantong = 0;
  2090. ceju.ExtractLines(cropContour, out rightOrdinateMiantong, rightMiddleMiantong - 5, rightMiddleMiantong + 5, 1);
  2091. double rightOrdinateMian_Jicaitong = 0;
  2092. ceju.ExtractLines(cropContour, out rightOrdinateMian_Jicaitong, rightMiddleMianJicaitong - 5, rightMiddleMianJicaitong + 5, 1);
  2093. double rightOrdinate1 = (rightOrdinateMiantong + rightOrdinateMian_Jicaitong) / 2;
  2094. double rightOrdinate3 = 0;
  2095. ceju.ExtractLines(cropContour, out rightOrdinate3, dataArea[2], dataArea[3], rightOrdinate1, -1);
  2096. rightMiantong_Jicaitong.Set(rightOrdinate3 - rightOrdinateMian_Jicaitong, rightMiddleMianJicaitong + border, (int)rightOrdinateMian_Jicaitong + upper, rightMiddleMianJicaitong + border, (int)rightOrdinate3 + upper);
  2097. UpdateSuccessLine();
  2098. double rightOrdinate4 = 0;
  2099. ceju.ExtractLines(cropContour, out rightOrdinate4, dataArea[2], dataArea[3], rightOrdinate3, 1);
  2100. double rightOrdinate5 = 0;
  2101. ceju.ExtractLines2(cropContour, out rightOrdinate5, dataArea[2], dataArea[3], cropContour.Rows - 1, 1);
  2102. double rightOrdinate4Copy = 0;
  2103. ceju.ExtractLines2(cropContour, out rightOrdinate4Copy, rightMiddleMianJicaitong - 5, rightMiddleMianJicaitong + 5, rightOrdinate5, -1);
  2104. if (rightOrdinate4Copy < rightOrdinate4 && rightOrdinate4Copy > 0)
  2105. rightOrdinate4 = rightOrdinate4Copy;
  2106. //求L2
  2107. Mat cropGreen = imageGreen[y[0], y[1], 0, imageGreen.Cols - 1];
  2108. //Cv2.ImWrite(@"C:\Users\54434\Desktop\cropGreen.jpg", cropGreen);
  2109. double leftOrdinate2 = 0;
  2110. double rightOrdinate2 = 0;
  2111. if (leftOrdinate1 + 10 < leftOrdinate3 - 10 && dataArea[0] < dataArea[1])
  2112. {
  2113. ceju.InsideLine(cropGreen, (int)leftOrdinate1 + 10, (int)leftOrdinate3 - 10, dataArea[0], dataArea[1], out leftOrdinate2);
  2114. leftMiantong.Set(leftOrdinate2 - leftOrdinateMiantong, leftMiddleMiantong + border, (int)leftOrdinateMiantong + upper, leftMiddleMiantong + border, (int)leftOrdinate2 + upper);
  2115. leftJicaitong.Set(leftOrdinate3 - leftOrdinate2, leftMiddleJicaitong + border, (int)leftOrdinate2 + upper, leftMiddleJicaitong + border, (int)leftOrdinate3 + upper);
  2116. UpdateSuccessLine();
  2117. UpdateSuccessLine();
  2118. }
  2119. if (rightOrdinate1 + 10 < rightOrdinate3 - 10 && dataArea[2] < dataArea[3])
  2120. {
  2121. ceju.InsideLine(cropGreen, (int)rightOrdinate1 + 10, (int)rightOrdinate3 - 10, dataArea[2], dataArea[3], out rightOrdinate2);
  2122. rightMiantong.Set(rightOrdinate2 - rightOrdinateMiantong, rightMiddleMiantong + border, (int)rightOrdinateMiantong + upper, rightMiddleMiantong + border, (int)rightOrdinate2 + upper);
  2123. rightJicaitong.Set(rightOrdinate3 - rightOrdinate2, rightMiddleJicaitong + border, (int)rightOrdinate2 + upper, rightMiddleJicaitong + border, (int)rightOrdinate3 + upper);
  2124. UpdateSuccessLine();
  2125. UpdateSuccessLine();
  2126. }
  2127. //Cv2.ImWrite(@"C:\Users\54434\Desktop\imageRed.jpg", imageRed);
  2128. //下孔径
  2129. Mat thresh = imageRed.Threshold(0, 1, ThresholdTypes.Otsu);
  2130. thresh = thresh[y[0], y[1], 0, thresh.Cols];
  2131. Mat seClose = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(3, 3));
  2132. Mat close = new Mat();
  2133. Cv2.MorphologyEx(thresh, close, MorphTypes.Close, seClose);
  2134. Mat fill = new Mat();
  2135. ceju.Fill(close, out fill, 1);
  2136. //Cv2.ImWrite(@"C:\Users\54434\Desktop\fill.jpg", fill * 255);
  2137. //ceju.ImageShow(fill * 255);
  2138. int[] apertureLow = new int[2];
  2139. //ceju.GetShenmangLowerAperture(fill, out apertureLow, (int)leftOrdinate4, (int)rightOrdinate4, (int)leftOrdinate5, (int)rightOrdinate5, dataArea);
  2140. ceju.GetLowerAperture(fill, out apertureLow, (int)leftOrdinate4 - 20, (int)rightOrdinate4 - 20, (int)leftOrdinate5 - 10, (int)rightOrdinate5 - 10, dataArea);
  2141. UpdateSuccessLine();
  2142. Mat apertureContour = cropContour.Clone();
  2143. Cv2.Rectangle(apertureContour, new Rect(0, (int)leftOrdinate2, cropContour.Cols, 1), new Scalar(1), -1);
  2144. ceju.Fill(apertureContour, out apertureContour, 1);
  2145. //上孔径
  2146. int[] leftAperture, rightAperture;
  2147. ceju.ShangKongjing(/*image[y[0],y[1],0,image.Cols-1],*/ apertureContour, apertureLow, (int)leftOrdinate3, (int)rightOrdinate3, out leftAperture, out rightAperture);
  2148. shangKongjing.Set(rightAperture[1] - leftAperture[1], leftAperture[1] + border, (int)leftOrdinate1 - 10 + upper, rightAperture[1] + border, (int)leftOrdinate1 - 10 + upper);
  2149. UpdateSuccessLine();
  2150. int[] apertureBegin = leftAperture;
  2151. int[] apertureEnd = rightAperture;
  2152. //孔径中点
  2153. //double middleAperture = (aperture[0] + aperture[1]) / 2;
  2154. double middleAperture = (leftAperture[1] + rightAperture[1]) / 2;
  2155. //求孔铜,求孔径起始点与曲面之间的最短距离,以及最短距离时的曲面坐标
  2156. //用新目标区域
  2157. Mat contour2 = new Mat();
  2158. double T = Cv2.Threshold(imageRed, contour2, 0, 1, ThresholdTypes.Otsu);
  2159. contour2 = imageRed.Threshold((T - 20), 1, ThresholdTypes.Binary);
  2160. Mat cropContour2 = contour2[y[0], y[1], 0, contour2.Cols];
  2161. //Cv2.ImWrite(@"C:\Users\54434\Desktop\cropContour2.jpg", cropContour2 * 255);
  2162. if (!this.isNewSuanfa)
  2163. {
  2164. double[] kongtong = new double[2];
  2165. int[] pointLeft = new int[2];
  2166. int[] pointRight = new int[2];
  2167. //按照从上到下顺序找白色点,计算第一个白色点到下面的端点,通过最小距离确认上面这个端点的位置
  2168. ceju.GetKongtong(cropContour2, apertureBegin, apertureEnd, out kongtong, out pointLeft, out pointRight);
  2169. leftKongtong.Set(kongtong[0], leftAperture[1] + border, leftAperture[0] + upper, pointLeft[1] + border, pointLeft[0] + upper);
  2170. rightKongtong.Set(kongtong[1], rightAperture[1] + border, rightAperture[0] + upper, pointRight[1] + border, pointRight[0] + upper);
  2171. UpdateSuccessLine();
  2172. UpdateSuccessLine();
  2173. }
  2174. else
  2175. {
  2176. //新孔铜
  2177. int[] pointLeft2 = new int[2];
  2178. int[] pointRight2 = new int[2];
  2179. double[] kongtong2 = new double[2];
  2180. int[] leftKongtongPoint = new int[2];
  2181. int[] rightKongtongPoint = new int[2];
  2182. Mat newImageRed = imageRed[y[0], y[1], 0, imageRed.Cols].Clone();
  2183. ceju.GetNewKongtong(newImageRed, cropContour2, leftAperture, rightAperture, leftOrdinateMiantong, leftMiddleMianJicaitong, leftOrdinate3, rightOrdinateMiantong, rightMiddleMianJicaitong, rightOrdinate3, out kongtong2, out leftKongtongPoint, out rightKongtongPoint, out pointLeft2, out pointRight2);
  2184. leftKongtong.Set(kongtong2[0], leftKongtongPoint[1] + border, leftKongtongPoint[0] + upper, pointLeft2[1] + border, pointLeft2[0] + upper);
  2185. rightKongtong.Set(kongtong2[1], rightKongtongPoint[1] + border, rightKongtongPoint[0] + upper, pointRight2[1] + border, pointRight2[0] + upper);
  2186. UpdateSuccessLine();
  2187. UpdateSuccessLine();
  2188. }
  2189. //最小孔环
  2190. int[] pointLeftRing = new int[2];
  2191. int[] pointRightRing = new int[2];
  2192. ceju.GetMinmumRing(cropContour2, (int)leftOrdinate1, (int)leftOrdinate4 - 50, 100, dataArea[0], out pointLeftRing, "left");
  2193. ceju.GetMinmumRing(cropContour2, (int)rightOrdinate1, (int)rightOrdinate4 - 50, dataArea[3], cropContour2.Cols - 100, out pointRightRing, "right");
  2194. //leftMinimumRing.Set((leftAperture[1] - pointLeftRing[1]), pointLeftRing[1] + border, (int)leftOrdinate1 - 10 + upper, leftAperture[1] + border, (int)leftOrdinate1 - 10 + upper);
  2195. //rightMinimumRing.Set((pointRightRing[1] - rightAperture[1]), pointRightRing[1] + border, (int)rightOrdinate1 - 10 + upper, rightAperture[1] + border, (int)rightOrdinate1 - 10 + upper);
  2196. leftMinimumRing.Set((leftKongtong.point1.X - pointLeftRing[1]), pointLeftRing[1] + border, (int)leftOrdinate1 - 10 + upper, leftKongtong.point1.X , (int)leftOrdinate1 - 10 + upper);
  2197. rightMinimumRing.Set((pointRightRing[1]- (rightKongtong.point1.X -border)), pointRightRing[1] + border, (int)rightOrdinate1 - 10 + upper, rightKongtong.point1.X , (int)rightOrdinate1 - 10 + upper);
  2198. //Cv2.Circle(imageRed, pointLeft3[1], pointLeft3[0], 1, 1, 1);
  2199. //new Window("imageRed_Line", WindowMode.Normal, imageRed);
  2200. //孔底与孔深
  2201. //提取曲面最凸点坐标
  2202. int[] curveVertex = new int[2];
  2203. //孔径平均高度
  2204. double middleApertureY;
  2205. ceju.CurveVertex(cropContour, apertureBegin, apertureEnd, out curveVertex, out middleApertureY);
  2206. Mat tempCrop = new Mat(cropContourOrigin, new Rect(apertureBegin[1]+50, (int)(leftOrdinate4 - 25), apertureEnd[1] - apertureBegin[1] - 100, (isCropFlag)?60:50)).CvtColor(ColorConversionCodes.BGR2GRAY);
  2207. double otsu = Cv2.Threshold(tempCrop, tempCrop, 0, 255, ThresholdTypes.Triangle);
  2208. int nums = int.MaxValue;
  2209. int row = 0;
  2210. bool blackwhite = false;
  2211. for(int i=0; i< tempCrop.Height; i++)
  2212. {
  2213. int v = tempCrop.Row[i].CountNonZero();
  2214. if(v == 0)
  2215. {
  2216. blackwhite = true;
  2217. }
  2218. if(blackwhite)
  2219. {
  2220. if(v ==0)
  2221. row = i;
  2222. }
  2223. else
  2224. {
  2225. if (tempCrop.Row[i].CountNonZero() < nums)
  2226. {
  2227. nums = tempCrop.Row[i].CountNonZero();
  2228. row = i;
  2229. }
  2230. }
  2231. }
  2232. //Cv2.ImWrite(@"C:\Users\zyh\Desktop\2.jpg", tempCrop);
  2233. //求L6
  2234. double t1 = 0;
  2235. double t2 = 0;
  2236. double ordinate6 = 0;
  2237. ceju.ChooseSize(leftOrdinate4, rightOrdinate4, "small", out t1);
  2238. ceju.ChooseSize(leftOrdinate5, rightOrdinate5, "small", out t2);
  2239. if (t1 - 20 < t2 - 10)
  2240. {
  2241. int tempDi = (int)(leftOrdinate4 - 30) + row + upper;
  2242. if ((tempDi+5) < leftOrdinate4 + upper) tempDi = (int)(leftOrdinate4 + 5 + upper);
  2243. if (tempDi == (leftOrdinate4 + upper)) tempDi = (int)(leftOrdinate4 + 5 + upper);
  2244. if (tempDi- (leftOrdinate4 + upper) > 25) tempDi = (int)(leftOrdinate4 + 5 + upper);
  2245. ceju.InsideLine(cropGreen, (int)t1 - 20, (int)t2 - 10, (int)middleAperture - 90, (int)middleAperture + 90, out ordinate6);
  2246. xiaKongjing.Set(apertureLow[1] - apertureLow[0], apertureLow[0] + border, (int)ordinate6 + 20 + upper, apertureLow[1] + border, (int)ordinate6 + 20 + upper);
  2247. kongdi.Set(Math.Abs(tempDi - (curveVertex[0] + upper)), curveVertex[1] + border, curveVertex[0] + upper, curveVertex[1] + border, tempDi/*(int)ordinate6 + upper*/);
  2248. UpdateSuccessLine();
  2249. if (leftOrdinate4 < rightOrdinate4)
  2250. kongdiyaoshiliang.Set(Math.Abs(tempDi - ((int)leftOrdinate4 + upper)), leftMiddleMianJicaitong + border, (int)leftOrdinate4 + upper, leftMiddleMianJicaitong + border, tempDi);
  2251. else
  2252. kongdiyaoshiliang.Set(Math.Abs(tempDi - ((int)rightOrdinate4 + upper)), rightMiddleMianJicaitong + border, (int)rightOrdinate4 + upper, rightMiddleMianJicaitong + border, tempDi);
  2253. UpdateSuccessLine();
  2254. }
  2255. #region[清理内存]
  2256. if (imageContour != null && !imageContour.IsDisposed)
  2257. {
  2258. imageContour.Dispose();
  2259. }
  2260. if (cropContour != null && !cropContour.IsDisposed)
  2261. {
  2262. cropContour.Dispose();
  2263. }
  2264. if (imageBlue != null && !imageBlue.IsDisposed)
  2265. {
  2266. imageBlue.Dispose();
  2267. }
  2268. if (imageGreen != null && !imageGreen.IsDisposed)
  2269. {
  2270. imageGreen.Dispose();
  2271. }
  2272. if (imageRed != null && !imageRed.IsDisposed)
  2273. {
  2274. imageRed.Dispose();
  2275. }
  2276. if (image != null && !image.IsDisposed)
  2277. {
  2278. image.Dispose();
  2279. }
  2280. if (cropContourOrigin != null && !cropContourOrigin.IsDisposed)
  2281. {
  2282. cropContourOrigin.Dispose();
  2283. }
  2284. if (cropGreen != null && !cropGreen.IsDisposed)
  2285. {
  2286. cropGreen.Dispose();
  2287. }
  2288. if (thresh != null && !thresh.IsDisposed)
  2289. {
  2290. thresh.Dispose();
  2291. }
  2292. if (seClose != null && !seClose.IsDisposed)
  2293. {
  2294. seClose.Dispose();
  2295. }
  2296. if (contour2 != null && !contour2.IsDisposed)
  2297. {
  2298. contour2.Dispose();
  2299. }
  2300. if (cropContour2 != null && !cropContour2.IsDisposed)
  2301. {
  2302. cropGreen.Dispose();
  2303. }
  2304. if (tempCrop != null && !tempCrop.IsDisposed)
  2305. {
  2306. tempCrop.Dispose();
  2307. }
  2308. this.result.Dispose();
  2309. ceju = null;
  2310. #endregion
  2311. GC.Collect();
  2312. }
  2313. }
  2314. public class DancengShenmangkong : AutoMeasureAnalysis
  2315. {
  2316. public DataInfor leftJicaitong = new DataInfor();
  2317. public DataInfor rightJicaitong = new DataInfor();
  2318. public DataInfor leftMiantong_Jicaitong = new DataInfor();
  2319. public DataInfor rightMiantong_Jicaitong = new DataInfor();
  2320. public DataInfor leftMiantong = new DataInfor();
  2321. public DataInfor rightMiantong = new DataInfor();
  2322. public DataInfor leftKongtong = new DataInfor();
  2323. public DataInfor rightKongtong = new DataInfor();
  2324. public DataInfor shangKongjing = new DataInfor();
  2325. public DataInfor xiaKongjing = new DataInfor();
  2326. public DataInfor kongdi = new DataInfor();
  2327. public DataInfor kongdiyaoshiliang = new DataInfor();
  2328. public DataInfor leftJiaohou = new DataInfor();
  2329. public DataInfor rightJiaohou = new DataInfor();
  2330. public DataInfor leftJiaoneisuo = new DataInfor();
  2331. public DataInfor rightJiaoneisuo = new DataInfor();
  2332. public DataInfor kongshen = new DataInfor();
  2333. public DataInfor leftMinimumRing = new DataInfor();
  2334. public DataInfor rightMinimumRing = new DataInfor();
  2335. private void Initialize()
  2336. {
  2337. dataInfors = new List<DataInfor>();
  2338. leftJicaitong.name = "左基材銅";
  2339. leftJicaitong.ID = "100014";
  2340. leftJicaitong.aliasName = "TMCNME";
  2341. rightJicaitong.name = "右基材銅";
  2342. rightJicaitong.ID = "100015";
  2343. rightJicaitong.aliasName = "YEKCUU";
  2344. leftMiantong_Jicaitong.name = "左面銅+基材銅";
  2345. leftMiantong_Jicaitong.ID = "100016";
  2346. leftMiantong_Jicaitong.aliasName = "GENRYR";
  2347. rightMiantong_Jicaitong.name = "右面銅+基材銅";
  2348. rightMiantong_Jicaitong.ID = "100017";
  2349. rightMiantong_Jicaitong.aliasName = "RIZGOG";
  2350. leftMiantong.name = "左面銅";
  2351. leftMiantong.ID = "100018";
  2352. leftMiantong.aliasName = "CWAJGB";
  2353. rightMiantong.name = "右面銅";
  2354. rightMiantong.ID = "100019";
  2355. rightMiantong.aliasName = "SICQLP";
  2356. leftKongtong.name = "左孔銅";
  2357. leftKongtong.ID = "100020";
  2358. leftKongtong.drawType = "MeasureLine";
  2359. leftKongtong.aliasName = "MKQRXB";
  2360. rightKongtong.name = "右孔銅";
  2361. rightKongtong.ID = "100021";
  2362. rightKongtong.drawType = "MeasureLine";
  2363. rightKongtong.aliasName = "SIFAJZ";
  2364. shangKongjing.name = "上孔徑";
  2365. shangKongjing.drawType = "MeasureHLine";
  2366. shangKongjing.ID = "100022";
  2367. shangKongjing.aliasName = "VAFZDF";
  2368. xiaKongjing.name = "下孔徑";
  2369. xiaKongjing.drawType = "MeasureHLine";
  2370. xiaKongjing.ID = "100023";
  2371. xiaKongjing.aliasName = "KKAQFF";
  2372. kongdi.name = "孔底";
  2373. kongdi.ID = "100024";
  2374. kongdi.aliasName = "QPMAHB";
  2375. kongdiyaoshiliang.name = "孔底咬蝕量";
  2376. kongdiyaoshiliang.ID = "100025";
  2377. kongdiyaoshiliang.aliasName = "XDLURS";
  2378. leftJiaohou.name = "左膠厚";
  2379. leftJiaohou.ID = "100027";
  2380. leftJiaohou.aliasName = "RJGNOS";
  2381. rightJiaohou.name = "右膠厚";
  2382. rightJiaohou.ID = "100028";
  2383. rightJiaohou.aliasName = "AHXFIU";
  2384. leftJiaoneisuo.name = "左膠内縮";
  2385. leftJiaoneisuo.ID = "100029";
  2386. leftJiaoneisuo.drawType = "MeasureHLine";
  2387. leftJiaoneisuo.aliasName = "TODTGP";
  2388. rightJiaoneisuo.name = "右膠内縮";
  2389. rightJiaoneisuo.ID = "100030";
  2390. rightJiaoneisuo.drawType = "MeasureHLine";
  2391. rightJiaoneisuo.aliasName = "QLIZTB";
  2392. kongshen.name = "孔深";
  2393. kongshen.ID = "100026";
  2394. kongshen.aliasName = "UCWPHT";
  2395. leftMinimumRing.name = "左孔環";
  2396. leftMinimumRing.ID = "200003";
  2397. leftMinimumRing.aliasName = "VACGES";
  2398. leftMinimumRing.drawType = "MeasureHLine";
  2399. rightMinimumRing.name = "右孔環";
  2400. rightMinimumRing.ID = "200004";
  2401. rightMinimumRing.aliasName = "XBCSKM";
  2402. rightMinimumRing.drawType = "MeasureHLine";
  2403. dataInfors.Add(leftJicaitong);
  2404. dataInfors.Add(rightJicaitong);
  2405. dataInfors.Add(leftMiantong_Jicaitong);
  2406. dataInfors.Add(rightMiantong_Jicaitong);
  2407. dataInfors.Add(leftMiantong);
  2408. dataInfors.Add(rightMiantong);
  2409. dataInfors.Add(leftKongtong);
  2410. dataInfors.Add(rightKongtong);
  2411. dataInfors.Add(shangKongjing);
  2412. dataInfors.Add(xiaKongjing);
  2413. dataInfors.Add(kongdi);
  2414. dataInfors.Add(kongdiyaoshiliang);
  2415. dataInfors.Add(leftJiaohou);
  2416. dataInfors.Add(rightJiaohou);
  2417. dataInfors.Add(leftJiaoneisuo);
  2418. dataInfors.Add(rightJiaoneisuo);
  2419. dataInfors.Add(kongshen);
  2420. dataInfors.Add(leftMinimumRing);
  2421. dataInfors.Add(rightMinimumRing);
  2422. number = 19;
  2423. success = 0;
  2424. wrongNumber = number;
  2425. }
  2426. public override void Compute(Mat image, bool isCropFlag, int X, int Y)
  2427. {
  2428. Initialize();
  2429. Ceju ceju = new Ceju();
  2430. //避免旋轉白邊的裁剪
  2431. int border = 0;
  2432. int upper = 0;
  2433. int tempupper = 0;
  2434. if (!isCropFlag)
  2435. {
  2436. int range = 0;
  2437. ceju.CropBothSide(image, out image, out range);
  2438. border += range;
  2439. upper += range;
  2440. tempupper += range;
  2441. }
  2442. // 一、预处理
  2443. DateTime t = DateTime.Now;
  2444. //获得蓝色,绿色,红色通道图片
  2445. Mat[] bgr = Cv2.Split(image);
  2446. Mat imageBlue = bgr[0];
  2447. Mat imageGreen = bgr[1];
  2448. Mat imageRed = bgr[2];
  2449. //獲取目標區域
  2450. Mat imageContour = new Mat();
  2451. ceju.GetContour(imageRed, out imageContour);
  2452. //上下裁剪
  2453. int[] y = new int[2];
  2454. Mat cropContour = new Mat();
  2455. ceju.Crop(imageContour, out y, out cropContour, isCropFlag);
  2456. upper += y[0];
  2457. if (isCropFlag)
  2458. {
  2459. upper += Y;
  2460. border = X;
  2461. }
  2462. //计算提取区域
  2463. int[] dataArea = new int[4];
  2464. ceju.GetMangkongDataArea(cropContour, out dataArea);
  2465. dataArea[1] -= 20;
  2466. dataArea[2] += 20;
  2467. int leftMiddleMianJicaitong = (dataArea[0] + dataArea[1]) / 2;
  2468. int leftMiddleMiantong = (leftMiddleMianJicaitong + dataArea[1]) / 2;
  2469. int leftMiddleJicaitong = (dataArea[0] + leftMiddleMianJicaitong) / 2;
  2470. int rightMiddleMianJicaitong = (dataArea[2] + dataArea[3]) / 2;
  2471. int rightMiddleMiantong = (rightMiddleMianJicaitong + dataArea[3]) / 2;
  2472. int rightMiddleJicaitong = (dataArea[2] + rightMiddleMianJicaitong) / 2;
  2473. //计算横线高度
  2474. double leftOrdinateMiantong = 0;
  2475. ceju.ExtractLines(cropContour, out leftOrdinateMiantong, leftMiddleMiantong - 5, leftMiddleMiantong + 5, 1);
  2476. double leftOrdinateMian_Jicaitong = 0;
  2477. ceju.ExtractLines(cropContour, out leftOrdinateMian_Jicaitong, leftMiddleMianJicaitong - 5, leftMiddleMianJicaitong + 5, 1);
  2478. double leftOrdinate1 = (leftOrdinateMiantong + leftOrdinateMian_Jicaitong) / 2;
  2479. double leftOrdinate3 = 0;
  2480. ceju.ExtractLines(cropContour, out leftOrdinate3, dataArea[0], dataArea[1], leftOrdinate1, -1);
  2481. leftMiantong_Jicaitong.Set(leftOrdinate3 - leftOrdinateMian_Jicaitong, leftMiddleMianJicaitong + border, (int)leftOrdinateMian_Jicaitong + upper, leftMiddleMianJicaitong + border, (int)leftOrdinate3 + upper);
  2482. UpdateSuccessLine();
  2483. double leftOrdinate4 = 0;
  2484. ceju.ExtractLines(cropContour, out leftOrdinate4, dataArea[0], dataArea[1], leftOrdinate3, 1);
  2485. double leftOrdinate5 = 0;
  2486. ceju.ExtractLines(cropContour, out leftOrdinate5, dataArea[0], dataArea[1], leftOrdinate4, -1);
  2487. //double leftOrdinate4Copy = 0;
  2488. //ceju.ExtractLines2(cropContour, out leftOrdinate4Copy, dataArea[0], dataArea[1], leftOrdinate5, -1);
  2489. //if (leftOrdinate4Copy < leftOrdinate4 && leftOrdinate4Copy > 0)
  2490. // leftOrdinate4 = leftOrdinate4Copy;
  2491. double rightOrdinateMiantong = 0;
  2492. ceju.ExtractLines(cropContour, out rightOrdinateMiantong, rightMiddleMiantong - 5, rightMiddleMiantong + 5, 1);
  2493. double rightOrdinateMian_Jicaitong = 0;
  2494. ceju.ExtractLines(cropContour, out rightOrdinateMian_Jicaitong, rightMiddleMianJicaitong - 5, rightMiddleMianJicaitong + 5, 1);
  2495. double rightOrdinate1 = (rightOrdinateMiantong + rightOrdinateMian_Jicaitong) / 2;
  2496. double rightOrdinate3 = 0;
  2497. ceju.ExtractLines(cropContour, out rightOrdinate3, dataArea[2], dataArea[3], rightOrdinate1, -1);
  2498. rightMiantong_Jicaitong.Set(rightOrdinate3 - rightOrdinateMian_Jicaitong, rightMiddleMianJicaitong + border, (int)rightOrdinateMian_Jicaitong + upper, rightMiddleMianJicaitong + border, (int)rightOrdinate3 + upper);
  2499. UpdateSuccessLine();
  2500. double rightOrdinate4 = 0;
  2501. ceju.ExtractLines(cropContour, out rightOrdinate4, dataArea[2], dataArea[3], rightOrdinate3, 1);
  2502. double rightOrdinate5 = 0;
  2503. ceju.ExtractLines(cropContour, out rightOrdinate5, dataArea[2], dataArea[3], rightOrdinate4, -1);
  2504. //double rightOrdinate4Copy = 0;
  2505. //ceju.ExtractLines2(cropContour, out rightOrdinate4Copy, dataArea[2], dataArea[3], rightOrdinate5, -1);
  2506. //求L2
  2507. Mat cropGreen = imageGreen[y[0], y[1], 0, imageGreen.Cols - 1];
  2508. double leftOrdinate2 = 0;
  2509. double rightOrdinate2 = 0;
  2510. if (leftOrdinate1 + 10 < leftOrdinate3 - 10 && dataArea[0] < dataArea[1])
  2511. {
  2512. ceju.InsideLine(cropGreen, (int)leftOrdinate1 + 10, (int)leftOrdinate3 - 10, dataArea[0], dataArea[1], out leftOrdinate2);
  2513. leftMiantong.Set(leftOrdinate2 - leftOrdinateMiantong, leftMiddleMiantong + border, (int)leftOrdinateMiantong + upper, leftMiddleMiantong + border, (int)leftOrdinate2 + upper);
  2514. leftJicaitong.Set(leftOrdinate3 - leftOrdinate2, leftMiddleJicaitong + border, (int)leftOrdinate2 + upper, leftMiddleJicaitong + border, (int)leftOrdinate3 + upper);
  2515. UpdateSuccessLine();
  2516. UpdateSuccessLine();
  2517. }
  2518. if (rightOrdinate1 + 10 < rightOrdinate3 - 10 && dataArea[2] < dataArea[3])
  2519. {
  2520. ceju.InsideLine(cropGreen, (int)rightOrdinate1 + 10, (int)rightOrdinate3 - 10, dataArea[2], dataArea[3], out rightOrdinate2);
  2521. rightMiantong.Set(rightOrdinate2 - rightOrdinateMiantong, rightMiddleMiantong + border, (int)rightOrdinateMiantong + upper, rightMiddleMiantong + border, (int)rightOrdinate2 + upper);
  2522. rightJicaitong.Set(rightOrdinate3 - rightOrdinate2, rightMiddleJicaitong + border, (int)rightOrdinate2 + upper, rightMiddleJicaitong + border, (int)rightOrdinate3 + upper);
  2523. UpdateSuccessLine();
  2524. UpdateSuccessLine();
  2525. }
  2526. //下孔径
  2527. Mat thresh = imageRed.Threshold(0, 1, ThresholdTypes.Otsu);
  2528. thresh = thresh[y[0], y[1], 0, thresh.Cols];
  2529. Mat seClose = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(3, 3));
  2530. Mat close = new Mat();
  2531. Cv2.MorphologyEx(thresh, close, MorphTypes.Close, seClose);
  2532. Mat fill = new Mat();
  2533. ceju.Fill(close, out fill, 1);
  2534. int[] apertureLow = new int[2];
  2535. ceju.GetShenmangLowerAperture(fill, out apertureLow, (int)leftOrdinate4, (int)rightOrdinate4, (int)leftOrdinate5, (int)rightOrdinate5, dataArea);
  2536. UpdateSuccessLine();
  2537. Mat apertureContour = cropContour.Clone();
  2538. Cv2.Rectangle(apertureContour, new Rect(0, (int)leftOrdinate2, cropContour.Cols, 1), new Scalar(1), -1);
  2539. ceju.Fill(apertureContour, out apertureContour, 1);
  2540. //上孔径
  2541. int[] leftAperture, rightAperture;
  2542. //ceju.ShangKongjing(/*image[y[0],y[1],0,image.Cols-1],*/ apertureContour, apertureLow, (int)leftOrdinate3, (int)rightOrdinate3, out leftAperture, out rightAperture);
  2543. ceju.ShenmangkongShangkongjing(cropContour, (int)leftOrdinate3, (int)rightOrdinate3, apertureLow, out leftAperture, out rightAperture);
  2544. int[] apertureBegin = leftAperture;
  2545. int[] apertureEnd = rightAperture;
  2546. //孔径中点
  2547. double middleAperture = (leftAperture[1] + rightAperture[1]) / 2;
  2548. shangKongjing.Set(rightAperture[1] - leftAperture[1], leftAperture[1] + border, (int)leftOrdinate1 - 10 + upper, rightAperture[1] + border, (int)leftOrdinate1 - 10 + upper);
  2549. UpdateSuccessLine();
  2550. //求孔铜,求孔径起始点与曲面之间的最短距离,以及最短距离时的曲面坐标
  2551. if (!isNewSuanfa)
  2552. {
  2553. double[] kongtong = new double[2];
  2554. int[] pointLeft = new int[2];
  2555. int[] pointRight = new int[2];
  2556. ceju.GetKongtong(cropContour, apertureBegin, apertureEnd, out kongtong, out pointLeft, out pointRight);
  2557. leftKongtong.Set(kongtong[0], leftAperture[1] + border, leftAperture[0] + upper, pointLeft[1] + border, pointLeft[0] + upper);
  2558. rightKongtong.Set(kongtong[1], rightAperture[1] + border, rightAperture[0] + upper, pointRight[1] + border, pointRight[0] + upper);
  2559. UpdateSuccessLine();
  2560. UpdateSuccessLine();
  2561. }
  2562. else
  2563. {
  2564. int[] pointLeft2 = new int[2];
  2565. int[] pointRight2 = new int[2];
  2566. double[] kongtong2 = new double[2];
  2567. int[] leftKongtongPoint = new int[2];
  2568. int[] rightKongtongPoint = new int[2];
  2569. Mat newImageRed = imageRed[y[0], y[1], 0, imageRed.Cols].Clone();
  2570. //ceju.GetNewKongtong(newImageRed, cropContour, leftAperture, rightAperture, leftOrdinateMiantong, leftMiddleMianJicaitong, leftOrdinate3, rightOrdinateMiantong, rightMiddleMianJicaitong, rightOrdinate3, out kongtong2, out leftKongtongPoint, out rightKongtongPoint, out pointLeft2, out pointRight2);
  2571. ceju.ShenmangkongNewKongtong(newImageRed, cropContour, (int)leftOrdinate2, (int)rightOrdinate2, leftAperture, rightAperture, out kongtong2, out leftKongtongPoint, out rightKongtongPoint, out pointLeft2, out pointRight2);
  2572. leftKongtong.Set(kongtong2[0], leftKongtongPoint[1] + border, leftKongtongPoint[0] + upper, pointLeft2[1] + border, pointLeft2[0] + upper);
  2573. rightKongtong.Set(kongtong2[1], rightKongtongPoint[1] + border, rightKongtongPoint[0] + upper, pointRight2[1] + border, pointRight2[0] + upper);
  2574. UpdateSuccessLine();
  2575. UpdateSuccessLine();
  2576. }
  2577. //最小孔环
  2578. int[] pointLeftRing = new int[2];
  2579. int[] pointRightRing = new int[2];
  2580. ceju.GetMinmumRing(cropContour, (int)leftOrdinate1, (int)leftOrdinate4 - 50, 100, dataArea[0], out pointLeftRing, "left");
  2581. ceju.GetMinmumRing(cropContour, (int)rightOrdinate1, (int)rightOrdinate4 - 50, dataArea[3], cropContour.Cols - 100, out pointRightRing, "right");
  2582. //leftMinimumRing.Set((leftAperture[1] - pointLeftRing[1]), pointLeftRing[1] + border, (int)leftOrdinate1 - 10 + upper, leftAperture[1] + border, (int)leftOrdinate1 - 10 + upper);
  2583. //rightMinimumRing.Set((pointRightRing[1] - rightAperture[1]), pointRightRing[1] + border, (int)rightOrdinate1 - 10 + upper, rightAperture[1] + border, (int)rightOrdinate1 - 10 + upper);
  2584. leftMinimumRing.Set((leftKongtong.point1.X - border - pointLeftRing[1]), pointLeftRing[1] + border, (int)leftOrdinate1 - 10 + upper, leftKongtong.point1.X, (int)leftOrdinate1 - 10 + upper);
  2585. rightMinimumRing.Set((pointRightRing[1] - (rightKongtong.point1.X - border)), pointRightRing[1] + border, (int)rightOrdinate1 - 10 + upper, rightKongtong.point1.X, (int)rightOrdinate1 - 10 + upper);
  2586. //孔底与孔深
  2587. //提取曲面最凸点坐标
  2588. int[] curveVertex = new int[2];
  2589. //孔径平均高度
  2590. double middleApertureY;
  2591. ceju.CurveVertex(cropContour, apertureBegin, apertureEnd, out curveVertex, out middleApertureY);
  2592. Mat tempCrop = new Mat(image, new Rect(apertureBegin[1] + 50, (int)(leftOrdinate4 + (isCropFlag ? y[0] : upper) - tempupper), apertureEnd[1] - apertureBegin[1] - 50, 35)).CvtColor(ColorConversionCodes.BGR2GRAY);
  2593. double otsu = Cv2.Threshold(tempCrop, tempCrop, 0, 255, ThresholdTypes.Triangle);
  2594. int nums = int.MaxValue;
  2595. int row = 0;
  2596. for (int i = 0; i < tempCrop.Height; i++)
  2597. {
  2598. if (tempCrop.Row[i].CountNonZero() < nums)
  2599. {
  2600. nums = tempCrop.Row[i].CountNonZero();
  2601. row = i;
  2602. }
  2603. }
  2604. int tempDi = (int)(leftOrdinate4 + upper + row); // - (isCropFlag ? 50 : 0));
  2605. if ((tempDi + 5) < leftOrdinate4 + upper) tempDi = (int)(leftOrdinate4 + 5 + upper);
  2606. if (tempDi == (leftOrdinate4 + upper)) tempDi = (int)(leftOrdinate4 + 5 + upper);
  2607. //if (tempDi - (leftOrdinate4 + upper) > 25) tempDi = (int)(leftOrdinate4 + 13 + upper);
  2608. //Cv2.ImWrite(@"C:\Users\zyh\Desktop\2.jpg", tempCrop);
  2609. //Cv2.ImWrite(@"C:\Users\zyh\Desktop\21.jpg", image);
  2610. if (leftOrdinate1 < rightOrdinate1)
  2611. kongshen.Set(curveVertex[0] - leftOrdinate1, curveVertex[1] + border, curveVertex[0] + upper, curveVertex[1] + border, (int)leftOrdinate1 + upper);
  2612. else
  2613. kongshen.Set(curveVertex[0] - rightOrdinate1, curveVertex[1] + border, curveVertex[0] + upper, curveVertex[1] + border, (int)rightOrdinate1 + upper);
  2614. UpdateSuccessLine();
  2615. //求L6
  2616. double t1 = 0;
  2617. double t2 = 0;
  2618. double ordinate6 = 0;
  2619. ceju.ChooseSize(leftOrdinate4, rightOrdinate4, "small", out t1);
  2620. ceju.ChooseSize(leftOrdinate5, rightOrdinate5, "small", out t2);
  2621. ceju.InsideLine(cropGreen, (int)t1 - 20, (int)t2 - 5, (int)middleAperture - 90, (int)middleAperture + 90, out ordinate6);
  2622. xiaKongjing.Set(apertureLow[1] - apertureLow[0], apertureLow[0] + border, (int)ordinate6 + 10 + upper, apertureLow[1] + border, (int)ordinate6 + 10 + upper);
  2623. kongdi.Set(Math.Abs(tempDi - (curveVertex[0] + upper)), curveVertex[1] + border, curveVertex[0] + upper, curveVertex[1] + border, tempDi/*(int)ordinate6 + upper*/);
  2624. UpdateSuccessLine();
  2625. if (leftOrdinate4 < rightOrdinate4)
  2626. kongdiyaoshiliang.Set(Math.Abs(tempDi - ((int)leftOrdinate4 + upper)), leftMiddleMianJicaitong + border, (int)leftOrdinate4 + upper, leftMiddleMianJicaitong + border, tempDi);
  2627. else
  2628. kongdiyaoshiliang.Set(Math.Abs(tempDi - ((int)rightOrdinate4 + upper)), rightMiddleMianJicaitong + border, (int)rightOrdinate4 + upper, rightMiddleMianJicaitong + border, tempDi);
  2629. UpdateSuccessLine();
  2630. //计算胶线
  2631. Mat cropRed = imageRed[y[0], y[1], 0, imageRed.Cols];
  2632. int[] ordinateGlue = new int[2];
  2633. ceju.GetGlue(cropRed, out ordinateGlue, (int)leftOrdinate3 + 20, (int)leftOrdinate4 - 20, (int)rightOrdinate3 + 20, (int)rightOrdinate4 - 20, dataArea);
  2634. leftJiaohou.Set(leftOrdinate4 - ordinateGlue[0], leftMiddleMianJicaitong + border, (int)leftOrdinate4 + upper, leftMiddleMianJicaitong + border, (int)ordinateGlue[0] + upper);
  2635. rightJiaohou.Set(rightOrdinate4 - ordinateGlue[1], rightMiddleMianJicaitong + border, (int)rightOrdinate4 + upper, rightMiddleMianJicaitong + border, (int)ordinateGlue[1] + upper);
  2636. UpdateSuccessLine();
  2637. UpdateSuccessLine();
  2638. // 十一、计算胶内缩
  2639. int[] upperWaist = new int[2];
  2640. int[] lowerWaist = new int[2];
  2641. ceju.GetWaist(fill, out upperWaist, out lowerWaist, (int)ordinateGlue[0] - 20, ordinateGlue, (int)leftOrdinate4 - 20, dataArea);
  2642. leftJiaoneisuo.Set(upperWaist[0] - lowerWaist[0], lowerWaist[0] + border, ordinateGlue[0] + upper, upperWaist[0] + border, ordinateGlue[0] + upper);
  2643. rightJiaoneisuo.Set(lowerWaist[1] - upperWaist[1], lowerWaist[1] + border, ordinateGlue[1] + upper, upperWaist[1] + border, ordinateGlue[1] + upper);
  2644. UpdateSuccessLine();
  2645. UpdateSuccessLine();
  2646. #region[释放内存]
  2647. if (imageBlue != null && !imageBlue.IsDisposed)
  2648. {
  2649. imageBlue.Dispose();
  2650. }
  2651. if (imageGreen != null && !imageGreen.IsDisposed)
  2652. {
  2653. imageGreen.Dispose();
  2654. }
  2655. if (imageRed != null && !imageRed.IsDisposed)
  2656. {
  2657. imageRed.Dispose();
  2658. }
  2659. if (imageContour != null && !imageContour.IsDisposed)
  2660. {
  2661. imageContour.Dispose();
  2662. }
  2663. if (cropContour != null && !cropContour.IsDisposed)
  2664. {
  2665. cropContour.Dispose();
  2666. }
  2667. if (cropGreen != null && !cropGreen.IsDisposed)
  2668. {
  2669. cropGreen.Dispose();
  2670. }
  2671. if (thresh != null && !thresh.IsDisposed)
  2672. {
  2673. thresh.Dispose();
  2674. }
  2675. if (seClose != null && !seClose.IsDisposed)
  2676. {
  2677. seClose.Dispose();
  2678. }
  2679. if (close != null && !close.IsDisposed)
  2680. {
  2681. close.Dispose();
  2682. }
  2683. if (fill != null && !fill.IsDisposed)
  2684. {
  2685. fill.Dispose();
  2686. }
  2687. if (apertureContour != null && !apertureContour.IsDisposed)
  2688. {
  2689. apertureContour.Dispose();
  2690. }
  2691. if (tempCrop != null && !tempCrop.IsDisposed)
  2692. {
  2693. tempCrop.Dispose();
  2694. }
  2695. if (cropRed != null && !cropRed.IsDisposed)
  2696. {
  2697. cropRed.Dispose();
  2698. }
  2699. #endregion
  2700. }
  2701. }
  2702. public class ShuangcengShenmangkong : AutoMeasureAnalysis
  2703. {
  2704. public DataInfor shangcengLeftJicaitong = new DataInfor();
  2705. public DataInfor shangcengRightJicaitong = new DataInfor();
  2706. public DataInfor shangcengLeftMiantong_Jicaitong = new DataInfor();
  2707. public DataInfor shangcengRightMiantong_Jicaitong = new DataInfor();
  2708. public DataInfor shangcengLeftMiantong = new DataInfor();
  2709. public DataInfor shangcengRightMiantong = new DataInfor();
  2710. public DataInfor shangcengLeftKongtong = new DataInfor();
  2711. public DataInfor shangcengRightKongtong = new DataInfor();
  2712. public DataInfor shangcengShangKongjing = new DataInfor();
  2713. public DataInfor shangcengXiaKongjing = new DataInfor();
  2714. public DataInfor shangcengKongdi = new DataInfor();
  2715. public DataInfor shangcengKongdiyaoshiliang = new DataInfor();
  2716. public DataInfor shangcengLeftJiaohou = new DataInfor();
  2717. public DataInfor shangcengRightJiaohou = new DataInfor();
  2718. public DataInfor shangcengLeftJiaoneisuo = new DataInfor();
  2719. public DataInfor shangcengRightJiaoneisuo = new DataInfor();
  2720. public DataInfor shangcengKongshen = new DataInfor();
  2721. public DataInfor shangcengLeftMinimumRing = new DataInfor();
  2722. public DataInfor shangcengRightMinimumRing = new DataInfor();
  2723. public DataInfor xiacengLeftJicaitong = new DataInfor();
  2724. public DataInfor xiacengRightJicaitong = new DataInfor();
  2725. public DataInfor xiacengLeftMiantong_Jicaitong = new DataInfor();
  2726. public DataInfor xiacengRightMiantong_Jicaitong = new DataInfor();
  2727. public DataInfor xiacengLeftMiantong = new DataInfor();
  2728. public DataInfor xiacengRightMiantong = new DataInfor();
  2729. public DataInfor xiacengLeftKongtong = new DataInfor();
  2730. public DataInfor xiacengRightKongtong = new DataInfor();
  2731. public DataInfor xiacengShangKongjing = new DataInfor();
  2732. public DataInfor xiacengXiaKongjing = new DataInfor();
  2733. public DataInfor xiacengKongdi = new DataInfor();
  2734. public DataInfor xiacengKongdiyaoshiliang = new DataInfor();
  2735. public DataInfor xiacengLeftJiaohou = new DataInfor();
  2736. public DataInfor xiacengRightJiaohou = new DataInfor();
  2737. public DataInfor xiacengLeftJiaoneisuo = new DataInfor();
  2738. public DataInfor xiacengRightJiaoneisuo = new DataInfor();
  2739. public DataInfor xiacengKongshen = new DataInfor();
  2740. public DataInfor xiacengLeftMinimumRing = new DataInfor();
  2741. public DataInfor xiacengRightMinimumRing = new DataInfor();
  2742. private void Initialize()
  2743. {
  2744. dataInfors = new List<DataInfor>();
  2745. shangcengLeftJicaitong.name = "上層左基材銅";
  2746. shangcengLeftJicaitong.ID = "100032";
  2747. shangcengLeftJicaitong.aliasName = "RJMHJL";
  2748. shangcengRightJicaitong.name = "上層右基材銅";
  2749. shangcengRightJicaitong.ID = "100033";
  2750. shangcengRightJicaitong.aliasName = "PFFQND";
  2751. shangcengLeftMiantong_Jicaitong.name = "上層左面銅+基材銅";
  2752. shangcengLeftMiantong_Jicaitong.ID = "100034";
  2753. shangcengLeftMiantong_Jicaitong.aliasName = "RJPRHV";
  2754. shangcengRightMiantong_Jicaitong.name = "上層右面銅+基材銅";
  2755. shangcengRightMiantong_Jicaitong.ID = "100035";
  2756. shangcengRightMiantong_Jicaitong.aliasName = "RJDWFA";
  2757. shangcengLeftMiantong.name = "上層左面銅";
  2758. shangcengLeftMiantong.ID = "100036";
  2759. shangcengLeftMiantong.aliasName = "ECZVTI";
  2760. shangcengRightMiantong.name = "上層右面銅";
  2761. shangcengRightMiantong.ID = "100037";
  2762. shangcengRightMiantong.aliasName = "UOBCYX";
  2763. shangcengLeftKongtong.name = "上層左孔銅";
  2764. shangcengLeftKongtong.ID = "100038";
  2765. shangcengLeftKongtong.drawType = "MeasureLine";
  2766. shangcengLeftKongtong.aliasName = "UOPHXC";
  2767. shangcengRightKongtong.name = "上層右孔銅";
  2768. shangcengRightKongtong.ID = "100039";
  2769. shangcengRightKongtong.drawType = "MeasureLine";
  2770. shangcengRightKongtong.aliasName = "QZQRQJ";
  2771. shangcengShangKongjing.name = "上層上孔徑";
  2772. shangcengShangKongjing.ID = "100040";
  2773. shangcengShangKongjing.drawType = "MeasureHLine";
  2774. shangcengShangKongjing.aliasName = "DNVEQI";
  2775. shangcengXiaKongjing.name = "上層下孔徑";
  2776. shangcengXiaKongjing.ID = "100041";
  2777. shangcengXiaKongjing.drawType = "MeasureHLine";
  2778. shangcengXiaKongjing.aliasName = "GHORIT";
  2779. shangcengKongdi.name = "上層孔底";
  2780. shangcengKongdi.ID = "100042";
  2781. shangcengKongdi.aliasName = "TZLQVC";
  2782. shangcengKongdiyaoshiliang.name = "上層孔底咬蝕量";
  2783. shangcengKongdiyaoshiliang.ID = "100043";
  2784. shangcengKongdiyaoshiliang.aliasName = "AYHPVK";
  2785. shangcengLeftJiaohou.name = "上層左膠厚";
  2786. shangcengLeftJiaohou.ID = "100045";
  2787. shangcengLeftJiaohou.aliasName = "OYYRYX";
  2788. shangcengRightJiaohou.name = "上層右膠厚";
  2789. shangcengRightJiaohou.ID = "100046";
  2790. shangcengRightJiaohou.aliasName = "JDZUDT";
  2791. shangcengLeftJiaoneisuo.name = "上層左膠内縮";
  2792. shangcengLeftJiaoneisuo.drawType = "MeasureHLine";
  2793. shangcengLeftJiaoneisuo.ID = "100047";
  2794. shangcengLeftJiaoneisuo.aliasName = "HBZSLZ";
  2795. shangcengRightJiaoneisuo.name = "上層右膠内縮";
  2796. shangcengRightJiaoneisuo.drawType = "MeasureHLine";
  2797. shangcengRightJiaoneisuo.ID = "100048";
  2798. shangcengRightJiaoneisuo.aliasName = "SLJJQL";
  2799. shangcengKongshen.name = "上層孔深";
  2800. shangcengKongshen.ID = "100044";
  2801. shangcengKongshen.aliasName = "WCXZED";
  2802. xiacengLeftJicaitong.name = "下層左基材銅";
  2803. xiacengLeftJicaitong.ID = "100049";
  2804. xiacengLeftJicaitong.aliasName = "GTQTBN";
  2805. xiacengRightJicaitong.name = "下層右基材銅";
  2806. xiacengRightJicaitong.ID = "100050";
  2807. xiacengRightJicaitong.aliasName = "QVHPWI";
  2808. xiacengLeftMiantong_Jicaitong.name = "下層左面銅+基材銅";
  2809. xiacengLeftMiantong_Jicaitong.ID = "100051";
  2810. xiacengLeftMiantong_Jicaitong.aliasName = "BZTDLX";
  2811. xiacengRightMiantong_Jicaitong.name = "下層右面銅+基材銅";
  2812. xiacengRightMiantong_Jicaitong.ID = "100052";
  2813. xiacengRightMiantong_Jicaitong.aliasName = "EONMCP";
  2814. xiacengLeftMiantong.name = "下層左面銅";
  2815. xiacengLeftMiantong.ID = "100053";
  2816. xiacengLeftMiantong.aliasName = "RWTXNQ";
  2817. xiacengRightMiantong.name = "下層右面銅";
  2818. xiacengRightMiantong.ID = "100054";
  2819. xiacengRightMiantong.aliasName = "QWNJRC";
  2820. xiacengLeftKongtong.name = "下層左孔銅";
  2821. xiacengLeftKongtong.ID = "100055";
  2822. xiacengLeftKongtong.drawType = "MeasureLine";
  2823. xiacengLeftKongtong.aliasName = "CMQVHF";
  2824. xiacengRightKongtong.name = "下層右孔銅";
  2825. xiacengRightKongtong.ID = "100056";
  2826. xiacengRightKongtong.drawType = "MeasureLine";
  2827. xiacengRightKongtong.aliasName = "RHBBML";
  2828. xiacengShangKongjing.name = "下層上孔徑";
  2829. xiacengShangKongjing.ID = "100057";
  2830. xiacengShangKongjing.drawType = "MeasureHLine";
  2831. xiacengShangKongjing.aliasName = "DAXAZU";
  2832. xiacengXiaKongjing.name = "下層下孔徑";
  2833. xiacengXiaKongjing.ID = "100058";
  2834. xiacengXiaKongjing.drawType = "MeasureHLine";
  2835. xiacengXiaKongjing.aliasName = "ZVWQIS";
  2836. xiacengKongdi.name = "下層孔底";
  2837. xiacengKongdi.ID = "100059";
  2838. xiacengKongdi.aliasName = "SXCBGU";
  2839. xiacengKongdiyaoshiliang.name = "下層孔底咬蝕量";
  2840. xiacengKongdiyaoshiliang.ID = "100060";
  2841. xiacengKongdiyaoshiliang.aliasName = "RIGVHF";
  2842. xiacengLeftJiaohou.name = "下層左膠厚";
  2843. xiacengLeftJiaohou.ID = "100062";
  2844. xiacengLeftJiaohou.aliasName = "DPHRWS";
  2845. xiacengRightJiaohou.name = "下層右膠厚";
  2846. xiacengRightJiaohou.ID = "100063";
  2847. xiacengRightJiaohou.aliasName = "GFAANK";
  2848. xiacengLeftJiaoneisuo.name = "下層左膠内縮";
  2849. xiacengLeftJiaoneisuo.ID = "100064";
  2850. xiacengLeftJiaoneisuo.drawType = "MeasureHLine";
  2851. xiacengLeftJiaoneisuo.aliasName = "CLKYTI";
  2852. xiacengRightJiaoneisuo.name = "下層右膠内縮";
  2853. xiacengRightJiaoneisuo.ID = "100065";
  2854. xiacengRightJiaoneisuo.drawType = "MeasureHLine";
  2855. xiacengRightJiaoneisuo.aliasName = "QTRIEK";
  2856. xiacengKongshen.name = "下層孔深";
  2857. xiacengKongshen.ID = "100061";
  2858. xiacengKongshen.aliasName = "FPNFSH";
  2859. shangcengLeftMinimumRing.name = "上層左孔環";
  2860. shangcengLeftMinimumRing.ID = "200005";
  2861. shangcengLeftMinimumRing.aliasName = "VACGJK";
  2862. shangcengLeftMinimumRing.drawType = "MeasureHLine";
  2863. shangcengRightMinimumRing.name = "上層右孔環";
  2864. shangcengRightMinimumRing.ID = "200006";
  2865. shangcengRightMinimumRing.aliasName = "XBCWRF";
  2866. shangcengRightMinimumRing.drawType = "MeasureHLine";
  2867. xiacengLeftMinimumRing.name = "下層左孔環";
  2868. xiacengLeftMinimumRing.ID = "200007";
  2869. xiacengLeftMinimumRing.aliasName = "GBCGJK";
  2870. xiacengLeftMinimumRing.drawType = "MeasureHLine";
  2871. xiacengRightMinimumRing.name = "下層右孔環";
  2872. xiacengRightMinimumRing.ID = "200008";
  2873. xiacengRightMinimumRing.aliasName = "PDCWRF";
  2874. xiacengRightMinimumRing.drawType = "MeasureHLine";
  2875. dataInfors.Add(shangcengLeftJicaitong);
  2876. dataInfors.Add(shangcengRightJicaitong);
  2877. dataInfors.Add(shangcengLeftMiantong_Jicaitong);
  2878. dataInfors.Add(shangcengRightMiantong_Jicaitong);
  2879. dataInfors.Add(shangcengLeftMiantong);
  2880. dataInfors.Add(shangcengRightMiantong);
  2881. dataInfors.Add(shangcengLeftKongtong);
  2882. dataInfors.Add(shangcengRightKongtong);
  2883. dataInfors.Add(shangcengShangKongjing);
  2884. dataInfors.Add(shangcengXiaKongjing);
  2885. dataInfors.Add(shangcengKongdi);
  2886. dataInfors.Add(shangcengKongdiyaoshiliang);
  2887. dataInfors.Add(shangcengLeftJiaohou);
  2888. dataInfors.Add(shangcengRightJiaohou);
  2889. dataInfors.Add(shangcengLeftJiaoneisuo);
  2890. dataInfors.Add(shangcengRightJiaoneisuo);
  2891. dataInfors.Add(shangcengKongshen);
  2892. dataInfors.Add(shangcengLeftMinimumRing);
  2893. dataInfors.Add(shangcengRightMinimumRing);
  2894. dataInfors.Add(xiacengLeftJicaitong);
  2895. dataInfors.Add(xiacengRightJicaitong);
  2896. dataInfors.Add(xiacengLeftMiantong_Jicaitong);
  2897. dataInfors.Add(xiacengRightMiantong_Jicaitong);
  2898. dataInfors.Add(xiacengLeftMiantong);
  2899. dataInfors.Add(xiacengRightMiantong);
  2900. dataInfors.Add(xiacengLeftKongtong);
  2901. dataInfors.Add(xiacengRightKongtong);
  2902. dataInfors.Add(xiacengShangKongjing);
  2903. dataInfors.Add(xiacengXiaKongjing);
  2904. dataInfors.Add(xiacengKongdi);
  2905. dataInfors.Add(xiacengKongdiyaoshiliang);
  2906. dataInfors.Add(xiacengLeftJiaohou);
  2907. dataInfors.Add(xiacengRightJiaohou);
  2908. dataInfors.Add(xiacengLeftJiaoneisuo);
  2909. dataInfors.Add(xiacengRightJiaoneisuo);
  2910. dataInfors.Add(xiacengKongshen);
  2911. dataInfors.Add(xiacengLeftMinimumRing);
  2912. dataInfors.Add(xiacengRightMinimumRing);
  2913. number = 38;
  2914. success = 0;
  2915. wrongNumber = number;
  2916. }
  2917. public override void Compute(Mat image, bool isCropFlag, int X, int Y)
  2918. {
  2919. Initialize();
  2920. Ceju ceju = new Ceju();
  2921. //避免旋轉白邊的裁剪
  2922. int range = 0;
  2923. if (!isCropFlag)
  2924. {
  2925. ceju.CropBothSide(image, out image, out range);
  2926. }
  2927. Mat imageGray = image.CvtColor(ColorConversionCodes.BGR2GRAY);
  2928. Mat contour = imageGray.Threshold(0, 1, ThresholdTypes.Otsu);
  2929. //裁剪
  2930. Mat crop = new Mat();
  2931. int[] y = new int[2];
  2932. ceju.CropShenmangkongShuangceng(contour, out y, out crop, isCropFlag);
  2933. //new Window("imageGray", WindowMode.Normal, imageGray);
  2934. //new Window("contour", WindowMode.Normal, contour);
  2935. //new Window("contour", WindowMode.Normal, contour * 255);
  2936. //new Window("crop", WindowMode.Normal, crop * 255);
  2937. //Cv2.WaitKey();
  2938. //上下分开
  2939. int y1 = 0, y2 = 0;
  2940. int[] sums = new int[crop.Rows];
  2941. for (int i = 0; i < crop.Rows; i++)
  2942. {
  2943. sums[i] = 0;
  2944. for (int j = 0; j < crop.Cols; j++)
  2945. {
  2946. sums[i] += crop.Get<byte>(i, j);
  2947. }
  2948. }
  2949. int length = sums.Length;
  2950. int[] partSum = sums.Skip(length / 4).Take(length / 2).ToArray();
  2951. int min = partSum.Min();
  2952. for (int i = length / 4; i < length / 4 * 3; i++)
  2953. {
  2954. if (sums[i] < min + 50)
  2955. {
  2956. y1 = i;
  2957. break;
  2958. }
  2959. }
  2960. for (int i = length / 4 * 3; i > length / 4; i--)
  2961. {
  2962. if (sums[i] < min + 50)
  2963. {
  2964. y2 = i;
  2965. break;
  2966. }
  2967. }
  2968. int middle = (y2 + y1) / 2 + y[0];
  2969. Mat crop1 = new Mat();
  2970. crop1 = image[y[0], middle, 0, crop.Cols - 1].Clone();
  2971. Mat crop2 = new Mat();
  2972. crop2 = image[middle, y[1], 0, crop.Cols - 1].Clone();
  2973. Cv2.Flip(crop2, crop2, FlipMode.X);
  2974. //new Window("crop1", WindowMode.Normal, crop1);
  2975. //new Window("crop2", WindowMode.Normal, crop2);
  2976. //Cv2.WaitKey();
  2977. int border = 0;
  2978. y[0] += range;
  2979. middle += range;
  2980. border = range;
  2981. if (isCropFlag)
  2982. {
  2983. y[0] += Y;
  2984. middle += Y;
  2985. border = X;
  2986. }
  2987. ComputeUpper(image, crop1, y, border);
  2988. ComputeLower(image, crop2, middle, border);
  2989. }
  2990. public void ComputeUpper(Mat image, Mat crop1, int[] y, int border)
  2991. {
  2992. Ceju ceju = new Ceju();
  2993. // 一、预处理
  2994. DateTime t = DateTime.Now;
  2995. //获得蓝色,绿色,红色通道图片
  2996. Mat[] bgr = Cv2.Split(crop1);
  2997. Mat imageBlue = bgr[0];
  2998. Mat imageGreen = bgr[1];
  2999. Mat imageRed = bgr[2];
  3000. // 獲取目標區域
  3001. Mat imageContour = new Mat();
  3002. ceju.GetShenmangkongContour(imageRed, out imageContour);
  3003. //计算提取区域
  3004. int[] dataArea = new int[4];
  3005. ceju.GetMangkongDataArea(imageContour, out dataArea);
  3006. dataArea[1] -= 20;
  3007. dataArea[2] += 20;
  3008. if (dataArea[1] - dataArea[0] < 5)
  3009. dataArea[0] -= 20;
  3010. if (dataArea[3] - dataArea[2] < 5)
  3011. dataArea[3] += 20;
  3012. int leftMiddleMianJicaitong = (dataArea[0] + dataArea[1]) / 2;
  3013. int leftMiddleMiantong = (leftMiddleMianJicaitong + dataArea[1]) / 2;
  3014. int leftMiddleJicaitong = (dataArea[0] + leftMiddleMianJicaitong) / 2;
  3015. int rightMiddleMianJicaitong = (dataArea[2] + dataArea[3]) / 2;
  3016. int rightMiddleMiantong = (rightMiddleMianJicaitong + dataArea[3]) / 2;
  3017. int rightMiddleJicaitong = (dataArea[2] + rightMiddleMianJicaitong) / 2;
  3018. //计算横线高度
  3019. double leftOrdinateMiantong = 0;
  3020. ceju.ExtractLines(imageContour, out leftOrdinateMiantong, leftMiddleMiantong - 5, leftMiddleMiantong + 5, 1);
  3021. double leftOrdinateMian_Jicaitong = 0;
  3022. ceju.ExtractLines(imageContour, out leftOrdinateMian_Jicaitong, leftMiddleMianJicaitong - 5, leftMiddleMianJicaitong + 5, 1);
  3023. double leftOrdinate1 = (leftOrdinateMiantong + leftOrdinateMian_Jicaitong) / 2;
  3024. double leftOrdinate3 = 0;
  3025. ceju.ExtractLines(imageContour, out leftOrdinate3, dataArea[0], dataArea[1], leftOrdinate1, -1);
  3026. shangcengLeftMiantong_Jicaitong.Set(leftOrdinate3 - leftOrdinateMian_Jicaitong, leftMiddleMianJicaitong + border, (int)leftOrdinateMian_Jicaitong + y[0], leftMiddleMianJicaitong + border, (int)leftOrdinate3 + y[0]);
  3027. UpdateSuccessLine();
  3028. double leftOrdinate4 = 0;
  3029. ceju.ExtractLines(imageContour, out leftOrdinate4, leftMiddleJicaitong - 10, leftMiddleJicaitong + 10, leftOrdinate3, 1);
  3030. double leftOrdinate5 = 0;
  3031. ceju.ExtractLines2(imageContour, out leftOrdinate5, leftMiddleJicaitong - 10, leftMiddleJicaitong + 10, 1);
  3032. double leftOrdinate4Copy = 0;
  3033. ceju.ExtractLines2(imageContour, out leftOrdinate4Copy, leftMiddleJicaitong - 10, leftMiddleJicaitong + 10, leftOrdinate5, -1);
  3034. if (leftOrdinate4Copy < leftOrdinate4)
  3035. leftOrdinate4 = leftOrdinate4Copy;
  3036. double rightOrdinateMiantong = 0;
  3037. ceju.ExtractLines(imageContour, out rightOrdinateMiantong, rightMiddleMiantong - 5, rightMiddleMiantong + 5, 1);
  3038. double rightOrdinateMian_Jicaitong = 0;
  3039. ceju.ExtractLines(imageContour, out rightOrdinateMian_Jicaitong, rightMiddleMianJicaitong - 5, rightMiddleMianJicaitong + 5, 1);
  3040. double rightOrdinate1 = (rightOrdinateMiantong + rightOrdinateMian_Jicaitong) / 2;
  3041. double rightOrdinate3 = 0;
  3042. ceju.ExtractLines(imageContour, out rightOrdinate3, dataArea[2], dataArea[3], rightOrdinate1, -1);
  3043. shangcengRightMiantong_Jicaitong.Set(rightOrdinate3 - rightOrdinateMian_Jicaitong, rightMiddleMianJicaitong + border, (int)rightOrdinateMian_Jicaitong + y[0], rightMiddleMianJicaitong + border, (int)rightOrdinate3 + y[0]);
  3044. UpdateSuccessLine();
  3045. double rightOrdinate4 = 0;
  3046. ceju.ExtractLines(imageContour, out rightOrdinate4, rightMiddleMiantong - 10, rightMiddleMiantong + 10, rightOrdinate3, 1);
  3047. double rightOrdinate5 = 0;
  3048. ceju.ExtractLines2(imageContour, out rightOrdinate5, rightMiddleMiantong - 10, rightMiddleMiantong + 10, 1);
  3049. double rightOrdinate4Copy = 0;
  3050. ceju.ExtractLines2(imageContour, out rightOrdinate4Copy, rightMiddleMiantong - 10, rightMiddleMiantong + 10, rightOrdinate5, -1);
  3051. if (rightOrdinate4Copy < rightOrdinate4)
  3052. rightOrdinate4 = rightOrdinate4Copy;
  3053. //求L2
  3054. double leftOrdinate2 = 0;
  3055. double rightOrdinate2 = 0;
  3056. if (leftOrdinate1 + 10 < leftOrdinate3 - 10 && dataArea[0] < dataArea[1])
  3057. {
  3058. ceju.InsideLine(imageGreen, (int)leftOrdinate1 + 10, (int)leftOrdinate3 - 10, dataArea[0], dataArea[1], out leftOrdinate2);
  3059. shangcengLeftMiantong.Set(leftOrdinate2 - leftOrdinateMiantong, leftMiddleMiantong + border, (int)leftOrdinateMiantong + y[0], leftMiddleMiantong + border, (int)leftOrdinate2 + y[0]);
  3060. shangcengLeftJicaitong.Set(leftOrdinate3 - leftOrdinate2, leftMiddleJicaitong + border, (int)leftOrdinate2 + y[0], leftMiddleJicaitong + border, (int)leftOrdinate3 + y[0]);
  3061. UpdateSuccessLine();
  3062. UpdateSuccessLine();
  3063. }
  3064. if (rightOrdinate1 + 10 < rightOrdinate3 - 10 && dataArea[2] < dataArea[3])
  3065. {
  3066. ceju.InsideLine(imageGreen, (int)rightOrdinate1 + 10, (int)rightOrdinate3 - 10, dataArea[2], dataArea[3], out rightOrdinate2);
  3067. shangcengRightMiantong.Set(rightOrdinate2 - rightOrdinateMiantong, rightMiddleMiantong + border, (int)rightOrdinateMiantong + y[0], rightMiddleMiantong + border, (int)rightOrdinate2 + y[0]);
  3068. shangcengRightJicaitong.Set(rightOrdinate3 - rightOrdinate2, rightMiddleJicaitong + border, (int)rightOrdinate2 + y[0], rightMiddleJicaitong + border, (int)rightOrdinate3 + y[0]);
  3069. UpdateSuccessLine();
  3070. UpdateSuccessLine();
  3071. }
  3072. //下孔径
  3073. Mat thresh = imageRed.Threshold(0, 1, ThresholdTypes.Otsu);
  3074. Mat seClose = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(3, 3));
  3075. Mat close = new Mat();
  3076. Cv2.MorphologyEx(thresh, close, MorphTypes.Close, seClose);
  3077. Mat fill = new Mat();
  3078. ceju.Fill(close, out fill, 1);
  3079. int[] apertureLow = new int[2];
  3080. ceju.GetShenmangLowerAperture(fill, out apertureLow, (int)leftOrdinate4, (int)rightOrdinate4, (int)leftOrdinate5, (int)rightOrdinate5, dataArea);
  3081. UpdateSuccessLine();
  3082. //上孔径
  3083. int[] leftAperture, rightAperture;
  3084. //ceju.ShangKongjing(imageContour, apertureLow, (int)leftOrdinate3, (int)rightOrdinate3, out leftAperture, out rightAperture);
  3085. ceju.ShenmangkongShangkongjing(imageContour, (int)leftOrdinate3, (int)rightOrdinate3, apertureLow, out leftAperture, out rightAperture);
  3086. int[] apertureBegin = leftAperture;
  3087. int[] apertureEnd = rightAperture;
  3088. //孔径中点
  3089. double middleAperture = (leftAperture[1] + rightAperture[1]) / 2;
  3090. shangcengShangKongjing.Set(rightAperture[1] - leftAperture[1], leftAperture[1] + border, (int)leftOrdinate1 - 30 + y[0], rightAperture[1] + border, (int)leftOrdinate1 - 30 + y[0]);
  3091. UpdateSuccessLine();
  3092. //求孔铜,求孔径起始点与曲面之间的最短距离,以及最短距离时的曲面坐标
  3093. if (!isNewSuanfa)
  3094. {
  3095. double[] kongtong = new double[2];
  3096. int[] pointLeft = new int[2];
  3097. int[] pointRight = new int[2];
  3098. ceju.GetKongtong(imageContour, apertureBegin, apertureEnd, out kongtong, out pointLeft, out pointRight);
  3099. shangcengLeftKongtong.Set(kongtong[0], leftAperture[1] + border, leftAperture[0] + y[0], pointLeft[1] + border, pointLeft[0] + y[0]);
  3100. shangcengRightKongtong.Set(kongtong[1], rightAperture[1] + border, rightAperture[0] + y[0], pointRight[1] + border, pointRight[0] + y[0]);
  3101. UpdateSuccessLine();
  3102. UpdateSuccessLine();
  3103. }
  3104. else
  3105. {
  3106. int[] pointLeft2 = new int[2];
  3107. int[] pointRight2 = new int[2];
  3108. double[] kongtong2 = new double[2];
  3109. int[] leftKongtongPoint = new int[2];
  3110. int[] rightKongtongPoint = new int[2];
  3111. //Mat newImageRed = imageRed[y[0], y[1], 0, imageRed.Cols].Clone();
  3112. //ceju.GetNewKongtong(imageRed, imageContour, leftAperture, rightAperture, leftOrdinateMiantong, leftMiddleMianJicaitong, leftOrdinate3, rightOrdinateMiantong, rightMiddleMianJicaitong, rightOrdinate3, out kongtong2, out leftKongtongPoint, out rightKongtongPoint, out pointLeft2, out pointRight2);
  3113. ceju.ShenmangkongNewKongtong(imageRed, imageContour, (int)leftOrdinate2, (int)rightOrdinate2, leftAperture, rightAperture, out kongtong2, out leftKongtongPoint, out rightKongtongPoint, out pointLeft2, out pointRight2);
  3114. shangcengLeftKongtong.Set(kongtong2[0], leftKongtongPoint[1] + border, leftKongtongPoint[0] + y[0], pointLeft2[1] + border, pointLeft2[0] + y[0]);
  3115. shangcengRightKongtong.Set(kongtong2[1], rightKongtongPoint[1] + border, rightKongtongPoint[0] + y[0], pointRight2[1] + border, pointRight2[0] + y[0]);
  3116. UpdateSuccessLine();
  3117. UpdateSuccessLine();
  3118. }
  3119. //最小孔环
  3120. int[] pointLeftRing = new int[2];
  3121. int[] pointRightRing = new int[2];
  3122. ceju.GetMinmumRing(imageContour, (int)leftOrdinate1, (int)leftOrdinate4 - 50, 100, dataArea[0], out pointLeftRing, "left");
  3123. ceju.GetMinmumRing(imageContour, (int)rightOrdinate1, (int)rightOrdinate4 - 50, dataArea[3], imageContour.Cols - 100, out pointRightRing, "right");
  3124. //leftMinimumRing.Set((leftAperture[1] - pointLeftRing[1]), pointLeftRing[1] + border, (int)leftOrdinate1 - 10 + upper, leftAperture[1] + border, (int)leftOrdinate1 - 10 + upper);
  3125. //rightMinimumRing.Set((pointRightRing[1] - rightAperture[1]), pointRightRing[1] + border, (int)rightOrdinate1 - 10 + upper, rightAperture[1] + border, (int)rightOrdinate1 - 10 + upper);
  3126. shangcengLeftMinimumRing.Set((shangcengLeftKongtong.point1.X - border - pointLeftRing[1]), pointLeftRing[1] + border, (int)leftOrdinate1 - 10 + y[0], shangcengLeftKongtong.point1.X, (int)leftOrdinate1 - 10 + y[0]);
  3127. shangcengRightMinimumRing.Set((pointRightRing[1] - (shangcengRightKongtong.point1.X - border)), pointRightRing[1] + border, (int)rightOrdinate1 - 10 + y[0], shangcengRightKongtong.point1.X, (int)rightOrdinate1 - 10 + y[0]);
  3128. //孔底与孔深
  3129. //提取曲面最凸点坐标
  3130. int[] curveVertex = new int[2];
  3131. //孔径平均高度
  3132. double middleApertureY;
  3133. ceju.CurveVertex(imageContour, apertureBegin, apertureEnd, out curveVertex, out middleApertureY);
  3134. if (curveVertex[0] > leftOrdinate1 || curveVertex[0] > rightOrdinate1)
  3135. {
  3136. if (leftOrdinate1 < rightOrdinate1)
  3137. shangcengKongshen.Set(Math.Abs(curveVertex[0] - leftOrdinate1), curveVertex[1] + border, curveVertex[0] + y[0], curveVertex[1] + border, (int)leftOrdinate1 + y[0]);
  3138. else
  3139. shangcengKongshen.Set(Math.Abs(curveVertex[0] - rightOrdinate1), curveVertex[1] + border, curveVertex[0] + y[0], curveVertex[1] + border, (int)rightOrdinate1 + y[0]);
  3140. }
  3141. else
  3142. {
  3143. if (leftOrdinate1 < rightOrdinate1)
  3144. shangcengKongshen.Set(Math.Abs(curveVertex[0] - rightOrdinate1), curveVertex[1] + border, curveVertex[0] + y[0], curveVertex[1] + border, (int)rightOrdinate1 + y[0]);
  3145. else
  3146. shangcengKongshen.Set(Math.Abs(curveVertex[0] - leftOrdinate1), curveVertex[1] + border, curveVertex[0] + y[0], curveVertex[1] + border, (int)leftOrdinate1 + y[0]);
  3147. }
  3148. UpdateSuccessLine();
  3149. //求L6
  3150. double t1 = 0;
  3151. double t2 = 0;
  3152. double ordinate6 = 0;
  3153. ceju.ChooseSize(leftOrdinate4, rightOrdinate4, "small", out t1);
  3154. ceju.ChooseSize(leftOrdinate5, rightOrdinate5, "small", out t2);
  3155. if (t1 > 20 && t2 > t1 + 5 + 20)
  3156. {
  3157. ceju.InsideLine(imageGreen, (int)t1 - 20, (int)t2 - 5, (int)middleAperture - 90, (int)middleAperture + 90, out ordinate6);
  3158. shangcengKongdi.Set(ordinate6 - curveVertex[0], curveVertex[1] + border, curveVertex[0] + y[0], curveVertex[1] + border, (int)ordinate6 + y[0]);
  3159. UpdateSuccessLine();
  3160. shangcengXiaKongjing.Set(apertureLow[1] - apertureLow[0], apertureLow[0] + border, (int)ordinate6 + 10 + y[0], apertureLow[1] + border, (int)ordinate6 + 10 + y[0]);
  3161. }
  3162. if (leftOrdinate4 < rightOrdinate4)
  3163. shangcengKongdiyaoshiliang.Set(ordinate6 - leftOrdinate4, leftMiddleMianJicaitong + border, (int)leftOrdinate4 + y[0], leftMiddleMianJicaitong + border, (int)ordinate6 + y[0]);
  3164. else
  3165. shangcengKongdiyaoshiliang.Set(ordinate6 - rightOrdinate4, rightMiddleMianJicaitong + border, (int)rightOrdinate4 + y[0], rightMiddleMianJicaitong + border, (int)ordinate6 + y[0]);
  3166. UpdateSuccessLine();
  3167. //计算胶线
  3168. int[] ordinateGlue = new int[2];
  3169. //CejuFunction.GetGlue(imageRed, dataArea, (int)leftOrdinate3 + 20, (int)leftOrdinate4 - 20, (int)rightOrdinate3 + 20, (int)rightOrdinate4 - 20, out ordinateGlue);
  3170. if (leftOrdinate3 > 0 && leftOrdinate4 > leftOrdinate3 + 20 && rightOrdinate3 > 0 && rightOrdinate4 > rightOrdinate3 + 20)
  3171. {
  3172. ceju.GetGlue2(imageRed, out ordinateGlue, (int)leftOrdinate3 + 5, (int)leftOrdinate4 - 5, (int)rightOrdinate3 + 5, (int)rightOrdinate4 - 5, dataArea);
  3173. shangcengLeftJiaohou.Set(leftOrdinate4 - ordinateGlue[0], leftMiddleMianJicaitong + border, (int)leftOrdinate4 + y[0], leftMiddleMianJicaitong + border, (int)ordinateGlue[0] + y[0]);
  3174. shangcengRightJiaohou.Set(rightOrdinate4 - ordinateGlue[1], rightMiddleMianJicaitong + border, (int)rightOrdinate4 + y[0], rightMiddleMianJicaitong + border, (int)ordinateGlue[1] + y[0]);
  3175. UpdateSuccessLine();
  3176. UpdateSuccessLine();
  3177. }
  3178. // 十一、计算胶内缩
  3179. int[] upperWaist = new int[2];
  3180. int[] lowerWaist = new int[2];
  3181. ceju.ChooseSize(ordinateGlue[0], ordinateGlue[1], "small", out t1);
  3182. if (t1 > 20 && leftOrdinate4 > 20 && rightOrdinate4 > 20)
  3183. {
  3184. ceju.GetWaistNew(fill, out upperWaist, out lowerWaist, (int)t1 - 20, ordinateGlue, (int)leftOrdinate4 - 20, (int)rightOrdinate4 - 20, dataArea);
  3185. shangcengLeftJiaoneisuo.Set(upperWaist[0] - lowerWaist[0], lowerWaist[0] + border, ordinateGlue[0] + y[0], upperWaist[0] + border, ordinateGlue[0] + y[0]);
  3186. shangcengRightJiaoneisuo.Set(lowerWaist[1] - upperWaist[1], lowerWaist[1] + border, ordinateGlue[1] + y[0], upperWaist[1] + border, ordinateGlue[1] + y[0]);
  3187. UpdateSuccessLine();
  3188. UpdateSuccessLine();
  3189. }
  3190. }
  3191. public void ComputeLower(Mat image, Mat crop2, int upper, int border)
  3192. {
  3193. Ceju ceju = new Ceju();
  3194. int rows = crop2.Rows;
  3195. int cols = crop2.Cols;
  3196. // 一、预处理
  3197. //获得蓝色,绿色,红色通道图片
  3198. Mat[] bgr = Cv2.Split(crop2);
  3199. Mat imageBlue = bgr[0];
  3200. Mat imageGreen = bgr[1];
  3201. Mat imageRed = bgr[2];
  3202. Mat imageContour = new Mat();
  3203. ceju.GetShenmangkongContour(imageRed, out imageContour);
  3204. //计算提取区域
  3205. int[] dataArea = new int[4];
  3206. ceju.GetMangkongDataArea(imageContour, out dataArea);
  3207. dataArea[1] -= 20;
  3208. dataArea[2] += 20;
  3209. if (dataArea[1] - dataArea[0] < 5)
  3210. dataArea[0] -= 20;
  3211. if (dataArea[3] - dataArea[2] < 5)
  3212. dataArea[3] += 20;
  3213. int leftMiddleMianJicaitong = (dataArea[0] + dataArea[1]) / 2;
  3214. int leftMiddleMiantong = (leftMiddleMianJicaitong + dataArea[1]) / 2;
  3215. int leftMiddleJicaitong = (dataArea[0] + leftMiddleMianJicaitong) / 2;
  3216. int rightMiddleMianJicaitong = (dataArea[2] + dataArea[3]) / 2;
  3217. int rightMiddleMiantong = (rightMiddleMianJicaitong + dataArea[3]) / 2;
  3218. int rightMiddleJicaitong = (dataArea[2] + rightMiddleMianJicaitong) / 2;
  3219. //计算横线高度
  3220. double leftOrdinateMiantong = 0;
  3221. ceju.ExtractLines(imageContour, out leftOrdinateMiantong, leftMiddleMiantong - 5, leftMiddleMiantong + 5, 1);
  3222. double leftOrdinateMian_Jicaitong = 0;
  3223. ceju.ExtractLines(imageContour, out leftOrdinateMian_Jicaitong, leftMiddleMianJicaitong - 5, leftMiddleMianJicaitong + 5, 1);
  3224. double leftOrdinate1 = (leftOrdinateMiantong + leftOrdinateMian_Jicaitong) / 2;
  3225. double leftOrdinate3 = 0;
  3226. ceju.ExtractLines(imageContour, out leftOrdinate3, dataArea[0], dataArea[1], leftOrdinate1, -1);
  3227. xiacengLeftMiantong_Jicaitong.Set(leftOrdinate3 - leftOrdinateMian_Jicaitong, leftMiddleMianJicaitong + border, rows - (int)leftOrdinateMian_Jicaitong + upper, leftMiddleMianJicaitong + border, rows - (int)leftOrdinate3 + upper);
  3228. UpdateSuccessLine();
  3229. double leftOrdinate4 = 0;
  3230. ceju.ExtractLines(imageContour, out leftOrdinate4, leftMiddleJicaitong - 10, leftMiddleJicaitong + 10, leftOrdinate3, 1);
  3231. double leftOrdinate5 = 0;
  3232. ceju.ExtractLines2(imageContour, out leftOrdinate5, leftMiddleJicaitong - 10, leftMiddleJicaitong + 10, 1);
  3233. double leftOrdinate4Copy = 0;
  3234. ceju.ExtractLines2(imageContour, out leftOrdinate4Copy, leftMiddleJicaitong - 10, leftMiddleJicaitong + 10, leftOrdinate5, -1);
  3235. if (leftOrdinate4Copy < leftOrdinate4)
  3236. leftOrdinate4 = leftOrdinate4Copy;
  3237. double rightOrdinateMiantong = 0;
  3238. ceju.ExtractLines(imageContour, out rightOrdinateMiantong, rightMiddleMiantong - 5, rightMiddleMiantong + 5, 1);
  3239. double rightOrdinateMian_Jicaitong = 0;
  3240. ceju.ExtractLines(imageContour, out rightOrdinateMian_Jicaitong, rightMiddleMianJicaitong - 5, rightMiddleMianJicaitong + 5, 1);
  3241. double rightOrdinate1 = (rightOrdinateMiantong + rightOrdinateMian_Jicaitong) / 2;
  3242. double rightOrdinate3 = 0;
  3243. ceju.ExtractLines(imageContour, out rightOrdinate3, dataArea[2], dataArea[3], rightOrdinate1, -1);
  3244. xiacengRightMiantong_Jicaitong.Set(rightOrdinate3 - rightOrdinateMian_Jicaitong, rightMiddleMianJicaitong + border, rows - (int)rightOrdinateMian_Jicaitong + upper, rightMiddleMianJicaitong + border, rows - (int)rightOrdinate3 + upper);
  3245. UpdateSuccessLine();
  3246. double rightOrdinate4 = 0;
  3247. ceju.ExtractLines(imageContour, out rightOrdinate4, rightMiddleMiantong - 10, rightMiddleMiantong + 10, rightOrdinate3, 1);
  3248. double rightOrdinate5 = 0;
  3249. ceju.ExtractLines2(imageContour, out rightOrdinate5, rightMiddleMiantong - 10, rightMiddleMiantong + 10, 1);
  3250. double rightOrdinate4Copy = 0;
  3251. ceju.ExtractLines2(imageContour, out rightOrdinate4Copy, rightMiddleMiantong - 10, rightMiddleMiantong + 10, rightOrdinate5, -1);
  3252. if (rightOrdinate4Copy < rightOrdinate4)
  3253. rightOrdinate4 = rightOrdinate4Copy;
  3254. //求L2
  3255. double leftOrdinate2 = 0;
  3256. double rightOrdinate2 = 0;
  3257. if (leftOrdinate1 + 10 < leftOrdinate3 - 10 && dataArea[0] < dataArea[1])
  3258. {
  3259. ceju.InsideLine(imageGreen, (int)leftOrdinate1 + 10, (int)leftOrdinate3 - 10, dataArea[0], dataArea[1], out leftOrdinate2);
  3260. xiacengLeftMiantong.Set(leftOrdinate2 - leftOrdinateMiantong, leftMiddleMiantong + border, rows - (int)leftOrdinateMiantong + upper, leftMiddleMiantong + border, rows - (int)leftOrdinate2 + upper);
  3261. xiacengLeftJicaitong.Set(leftOrdinate3 - leftOrdinate2, leftMiddleJicaitong + border, rows - (int)leftOrdinate2 + upper, leftMiddleJicaitong + border, rows - (int)leftOrdinate3 + upper);
  3262. UpdateSuccessLine();
  3263. UpdateSuccessLine();
  3264. }
  3265. if (rightOrdinate1 + 10 < rightOrdinate3 - 10 && dataArea[2] < dataArea[3])
  3266. {
  3267. ceju.InsideLine(imageGreen, (int)rightOrdinate1 + 10, (int)rightOrdinate3 - 10, dataArea[2], dataArea[3], out rightOrdinate2);
  3268. xiacengRightMiantong.Set(rightOrdinate2 - rightOrdinateMiantong, rightMiddleMiantong + border, rows - (int)rightOrdinateMiantong + upper, rightMiddleMiantong + border, rows - (int)rightOrdinate2 + upper);
  3269. xiacengRightJicaitong.Set(rightOrdinate3 - rightOrdinate2, rightMiddleJicaitong + border, rows - (int)rightOrdinate2 + upper, rightMiddleJicaitong + border, rows - (int)rightOrdinate3 + upper);
  3270. UpdateSuccessLine();
  3271. UpdateSuccessLine();
  3272. }
  3273. //下孔径
  3274. Mat thresh = imageRed.Threshold(0, 1, ThresholdTypes.Otsu);
  3275. Mat seClose = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(3, 3));
  3276. Mat close = new Mat();
  3277. Cv2.MorphologyEx(thresh, close, MorphTypes.Close, seClose);
  3278. Mat fill = new Mat();
  3279. ceju.Fill(close, out fill, 1);
  3280. int[] apertureLow = new int[2];
  3281. ceju.GetShenmangLowerAperture(fill, out apertureLow, (int)leftOrdinate4, (int)rightOrdinate4, (int)leftOrdinate5, (int)rightOrdinate5, dataArea);
  3282. UpdateSuccessLine();
  3283. //上孔径
  3284. int[] leftAperture, rightAperture;
  3285. //ceju.ShangKongjing(imageContour, apertureLow, (int)leftOrdinate3, (int)rightOrdinate3, out leftAperture, out rightAperture);
  3286. ceju.ShenmangkongShangkongjing(imageContour, (int)leftOrdinate3, (int)rightOrdinate3, apertureLow, out leftAperture, out rightAperture);
  3287. int[] apertureBegin = leftAperture;
  3288. int[] apertureEnd = rightAperture;
  3289. //孔径中点
  3290. double middleAperture = (leftAperture[1] + rightAperture[1]) / 2;
  3291. xiacengShangKongjing.Set(rightAperture[1] - leftAperture[1], leftAperture[1] + border, rows - ((int)leftOrdinate1 - 30) + upper, rightAperture[1] + border, rows - ((int)leftOrdinate1 - 30) + upper);
  3292. UpdateSuccessLine();
  3293. //求孔铜,求孔径起始点与曲面之间的最短距离,以及最短距离时的曲面坐标
  3294. if (!isNewSuanfa)
  3295. {
  3296. double[] kongtong = new double[2];
  3297. int[] pointLeft = new int[2];
  3298. int[] pointRight = new int[2];
  3299. ceju.GetKongtong(imageContour, apertureBegin, apertureEnd, out kongtong, out pointLeft, out pointRight);
  3300. xiacengLeftKongtong.Set(kongtong[0], leftAperture[1] + border, rows - leftAperture[0] + upper, pointLeft[1] + border, rows - pointLeft[0] + upper);
  3301. xiacengRightKongtong.Set(kongtong[1], rightAperture[1] + border, rows - rightAperture[0] + upper, pointRight[1] + border, rows - pointRight[0] + upper);
  3302. UpdateSuccessLine();
  3303. UpdateSuccessLine();
  3304. }
  3305. else
  3306. {
  3307. int[] pointLeft2 = new int[2];
  3308. int[] pointRight2 = new int[2];
  3309. double[] kongtong2 = new double[2];
  3310. int[] leftKongtongPoint = new int[2];
  3311. int[] rightKongtongPoint = new int[2];
  3312. //Mat newImageRed = imageRed[y[0], y[1], 0, imageRed.Cols].Clone();
  3313. //ceju.GetNewKongtong(imageRed, imageContour, leftAperture, rightAperture, leftOrdinateMiantong, leftMiddleMianJicaitong, leftOrdinate3, rightOrdinateMiantong, rightMiddleMianJicaitong, rightOrdinate3, out kongtong2, out leftKongtongPoint, out rightKongtongPoint, out pointLeft2, out pointRight2);
  3314. ceju.ShenmangkongNewKongtong(imageRed, imageContour, (int)leftOrdinate2, (int)rightOrdinate2, leftAperture, rightAperture, out kongtong2, out leftKongtongPoint, out rightKongtongPoint, out pointLeft2, out pointRight2);
  3315. xiacengLeftKongtong.Set(kongtong2[0], leftKongtongPoint[1] + border, rows - leftKongtongPoint[0] + upper, pointLeft2[1] + border, rows - pointLeft2[0] + upper);
  3316. xiacengRightKongtong.Set(kongtong2[1], rightKongtongPoint[1] + border, rows - rightKongtongPoint[0] + upper, pointRight2[1] + border, rows - pointRight2[0] + upper);
  3317. UpdateSuccessLine();
  3318. UpdateSuccessLine();
  3319. }
  3320. //最小孔环
  3321. int[] pointLeftRing = new int[2];
  3322. int[] pointRightRing = new int[2];
  3323. ceju.GetMinmumRing(imageContour, (int)leftOrdinate1, (int)leftOrdinate4 - 50, 100, dataArea[0], out pointLeftRing, "left");
  3324. ceju.GetMinmumRing(imageContour, (int)rightOrdinate1, (int)rightOrdinate4 - 50, dataArea[3], imageContour.Cols - 100, out pointRightRing, "right");
  3325. //leftMinimumRing.Set((leftAperture[1] - pointLeftRing[1]), pointLeftRing[1] + border, (int)leftOrdinate1 - 10 + upper, leftAperture[1] + border, (int)leftOrdinate1 - 10 + upper);
  3326. //rightMinimumRing.Set((pointRightRing[1] - rightAperture[1]), pointRightRing[1] + border, (int)rightOrdinate1 - 10 + upper, rightAperture[1] + border, (int)rightOrdinate1 - 10 + upper);
  3327. xiacengLeftMinimumRing.Set((xiacengLeftKongtong.point1.X - border - pointLeftRing[1]), pointLeftRing[1] + border, rows - (int)leftOrdinate1 + 10 + upper, xiacengLeftKongtong.point1.X, rows - (int)leftOrdinate1 + 10 + upper);
  3328. xiacengRightMinimumRing.Set((pointRightRing[1] - (xiacengRightKongtong.point1.X - border)), pointRightRing[1] + border, rows - (int)rightOrdinate1 + 10 + upper, xiacengRightKongtong.point1.X, rows - (int)rightOrdinate1 + 10 + upper);
  3329. //孔底与孔深
  3330. //提取曲面最凸点坐标
  3331. int[] curveVertex = new int[2];
  3332. //孔径平均高度
  3333. double middleApertureY;
  3334. ceju.CurveVertex(imageContour, apertureBegin, apertureEnd, out curveVertex, out middleApertureY);
  3335. if (curveVertex[0] > leftOrdinate1 || curveVertex[0] > rightOrdinate1)
  3336. {
  3337. if (leftOrdinate1 < rightOrdinate1)
  3338. xiacengKongshen.Set(Math.Abs(curveVertex[0] - leftOrdinate1), curveVertex[1] + border, rows - curveVertex[0] + upper, curveVertex[1] + border, rows - (int)leftOrdinate1 + upper);
  3339. else
  3340. xiacengKongshen.Set(Math.Abs(curveVertex[0] - rightOrdinate1), curveVertex[1] + border, rows - curveVertex[0] + upper, curveVertex[1] + border, rows - (int)rightOrdinate1 + upper);
  3341. }
  3342. else
  3343. {
  3344. if (leftOrdinate1 < rightOrdinate1)
  3345. xiacengKongshen.Set(Math.Abs(curveVertex[0] - rightOrdinate1), curveVertex[1] + border, rows - curveVertex[0] + upper, curveVertex[1] + border, rows - (int)rightOrdinate1 + upper);
  3346. else
  3347. xiacengKongshen.Set(Math.Abs(curveVertex[0] - leftOrdinate1), curveVertex[1] + border, rows - curveVertex[0] + upper, curveVertex[1] + border, rows - (int)leftOrdinate1 + upper);
  3348. }
  3349. UpdateSuccessLine();
  3350. //求L6
  3351. double t1 = 0;
  3352. double t2 = 0;
  3353. double ordinate6 = 0;
  3354. ceju.ChooseSize(leftOrdinate4, rightOrdinate4, "small", out t1);
  3355. ceju.ChooseSize(leftOrdinate5, rightOrdinate5, "small", out t2);
  3356. if (t1 > 20 && t2 > t1 + 5 + 20)
  3357. {
  3358. ceju.InsideLine(imageGreen, (int)t1 - 20, (int)t2 - 5, (int)middleAperture - 90, (int)middleAperture + 90, out ordinate6);
  3359. xiacengXiaKongjing.Set(apertureLow[1] - apertureLow[0], apertureLow[0] + border, rows - ((int)ordinate6 + 10) + upper, apertureLow[1] + border, rows - ((int)ordinate6 + 10) + upper);
  3360. xiacengKongdi.Set(ordinate6 - curveVertex[0], curveVertex[1] + border, rows - curveVertex[0] + upper, curveVertex[1] + border, rows - (int)ordinate6 + upper);
  3361. UpdateSuccessLine();
  3362. }
  3363. if (leftOrdinate4 < rightOrdinate4)
  3364. xiacengKongdiyaoshiliang.Set(ordinate6 - leftOrdinate4, leftMiddleMianJicaitong + border, rows - (int)leftOrdinate4 + upper, leftMiddleMianJicaitong + border, rows - (int)ordinate6 + upper);
  3365. else
  3366. xiacengKongdiyaoshiliang.Set(ordinate6 - rightOrdinate4, rightMiddleMianJicaitong + border, rows - (int)rightOrdinate4 + upper, rightMiddleMianJicaitong + border, rows - (int)ordinate6 + upper);
  3367. UpdateSuccessLine();
  3368. //计算胶线
  3369. int[] ordinateGlue = new int[2];
  3370. if (leftOrdinate3 > 0 && leftOrdinate4 > leftOrdinate3 + 20 && rightOrdinate3 > 0 && rightOrdinate4 > rightOrdinate3 + 20)
  3371. {
  3372. ceju.GetGlue2(imageRed, out ordinateGlue, (int)leftOrdinate3 + 5, (int)leftOrdinate4 - 5, (int)rightOrdinate3 + 5, (int)rightOrdinate4 - 5, dataArea);
  3373. xiacengLeftJiaohou.Set(leftOrdinate4 - ordinateGlue[0], leftMiddleMianJicaitong + border, rows - (int)leftOrdinate4 + upper, leftMiddleMianJicaitong + border, (int)rows - ordinateGlue[0] + upper);
  3374. xiacengRightJiaohou.Set(rightOrdinate4 - ordinateGlue[1], rightMiddleMianJicaitong + border, rows - (int)rightOrdinate4 + upper, rightMiddleMianJicaitong + border, (int)rows - ordinateGlue[1] + upper);
  3375. UpdateSuccessLine();
  3376. UpdateSuccessLine();
  3377. }
  3378. // 十一、计算胶内缩
  3379. int[] upperWaist = new int[2];
  3380. int[] lowerWaist = new int[2];
  3381. ceju.ChooseSize(ordinateGlue[0], ordinateGlue[1], "small", out t1);
  3382. if (t1 > 20 && leftOrdinate4 > 20 && rightOrdinate4 > 20)
  3383. {
  3384. ceju.GetWaistNew(fill, out upperWaist, out lowerWaist, (int)t1 - 20, ordinateGlue, (int)leftOrdinate4 - 20, (int)rightOrdinate4 - 20, dataArea);
  3385. xiacengLeftJiaoneisuo.Set(upperWaist[0] - lowerWaist[0], lowerWaist[0] + border, rows - ordinateGlue[0] + upper, upperWaist[0] + border, rows - ordinateGlue[0] + upper);
  3386. xiacengRightJiaoneisuo.Set(lowerWaist[1] - upperWaist[1], lowerWaist[1] + border, rows - ordinateGlue[1] + upper, upperWaist[1] + border, rows - ordinateGlue[1] + upper);
  3387. UpdateSuccessLine();
  3388. UpdateSuccessLine();
  3389. }
  3390. #region
  3391. if (imageBlue != null && !imageBlue.IsDisposed)
  3392. {
  3393. imageBlue.Dispose();
  3394. }
  3395. if (imageGreen != null && !imageGreen.IsDisposed)
  3396. {
  3397. imageGreen.Dispose();
  3398. }
  3399. if (imageRed != null && !imageRed.IsDisposed)
  3400. {
  3401. imageRed.Dispose();
  3402. }
  3403. if (imageContour != null && !imageContour.IsDisposed)
  3404. {
  3405. imageContour.Dispose();
  3406. }
  3407. if (thresh != null && !thresh.IsDisposed)
  3408. {
  3409. thresh.Dispose();
  3410. }
  3411. if (seClose != null && !seClose.IsDisposed)
  3412. {
  3413. seClose.Dispose();
  3414. }
  3415. if (close != null && !close.IsDisposed)
  3416. {
  3417. close.Dispose();
  3418. }
  3419. if (fill != null && !fill.IsDisposed)
  3420. {
  3421. fill.Dispose();
  3422. }
  3423. #endregion
  3424. }
  3425. }
  3426. public class DancengShikeyinzi : AutoMeasureAnalysis
  3427. {
  3428. public DataInfor shangfu = new DataInfor();
  3429. public DataInfor xiafu = new DataInfor();
  3430. public DataInfor tonghou = new DataInfor();
  3431. public Mat result = new Mat();
  3432. private void Initialize()
  3433. {
  3434. shangfu.name = "上幅";
  3435. shangfu.drawType = "MeasureHLine";
  3436. shangfu.ID = "100168";
  3437. shangfu.aliasName = "VTEDWG";
  3438. xiafu.name = "下幅";
  3439. xiafu.drawType = "MeasureHLine";
  3440. xiafu.ID = "100169";
  3441. xiafu.aliasName = "KBGGBB";
  3442. tonghou.name = "銅厚";
  3443. tonghou.ID = "100170";
  3444. tonghou.aliasName = "XUCGOJ";
  3445. dataInfors.Add(shangfu);
  3446. dataInfors.Add(xiafu);
  3447. dataInfors.Add(tonghou);
  3448. number = 3;
  3449. wrongNumber = number;
  3450. success = 0;
  3451. }
  3452. public override void Compute(Mat image, bool isCropFlag, int X, int Y)
  3453. {
  3454. Initialize();
  3455. Ceju ceju = new Ceju();
  3456. Mat[] bgr = Cv2.Split(image);
  3457. Mat imageBlue = bgr[0];
  3458. Mat imageGreen = bgr[1];
  3459. Mat imageRed = bgr[2];
  3460. Mat imageContour = new Mat();
  3461. //ceju.GetContour(imageRed, out imageContour);
  3462. double t = Cv2.Threshold(imageBlue, imageContour, 0, 1, ThresholdTypes.Otsu);
  3463. if (t < 190)
  3464. imageContour = imageBlue.Threshold(t + 50, 1, ThresholdTypes.Binary);
  3465. ceju.GetArea(imageContour, out imageContour, 20000, false);
  3466. if ((int)imageContour.Sum() < 10000)
  3467. {
  3468. t = Cv2.Threshold(imageRed, imageContour, 0, 1, ThresholdTypes.Otsu);
  3469. if (t < 190)
  3470. imageContour = imageRed.Threshold(t + 50, 1, ThresholdTypes.Binary);
  3471. }
  3472. //數據提取區域
  3473. int[] dataArea = new int[4];
  3474. ceju.SKYZDataArea(imageContour, out dataArea,isCropFlag);
  3475. Mat cropContour = imageContour[dataArea[0], dataArea[1], dataArea[2], dataArea[3]];
  3476. //new Window("cropContour", WindowMode.Normal, cropContour * 255);
  3477. //Cv2.WaitKey();
  3478. if (isCropFlag)
  3479. {
  3480. dataArea[0] += Y;
  3481. dataArea[2] += X;
  3482. }
  3483. //提取上幅
  3484. int upperLineValue;
  3485. int[] upperLineOrdinate = new int[3];
  3486. //ceju.UpperLine(cropContour, out upperLineValue, out upperLineOrdinate);
  3487. ceju.UpperLine2(cropContour, out upperLineValue, out upperLineOrdinate);
  3488. shangfu.Set(upperLineValue, upperLineOrdinate[1] + dataArea[2], upperLineOrdinate[0] + dataArea[0] - 30, upperLineOrdinate[2] + dataArea[2], upperLineOrdinate[0] + dataArea[0] - 30);
  3489. UpdateSuccessLine();
  3490. //提取下幅
  3491. int lowerLineValue = dataArea[3]+X - dataArea[2];
  3492. int[] lowerLineOrdinate = { dataArea[1], dataArea[2], dataArea[3] };
  3493. xiafu.Set(lowerLineValue, lowerLineOrdinate[1], lowerLineOrdinate[0] + Y, lowerLineOrdinate[2] + X, lowerLineOrdinate[0] + Y);
  3494. UpdateSuccessLine();
  3495. //提取銅厚
  3496. int tonghouValue;
  3497. int[] tonghouOrdinate = new int[3];
  3498. ceju.Zonghou(cropContour, out tonghouValue, out tonghouOrdinate);
  3499. tonghou.Set(tonghouValue, tonghouOrdinate[0] + dataArea[2], tonghouOrdinate[1] + dataArea[0], tonghouOrdinate[0] + dataArea[2], tonghouOrdinate[2] + dataArea[0]);
  3500. UpdateSuccessLine();
  3501. #region
  3502. if (imageBlue != null && !imageBlue.IsDisposed)
  3503. {
  3504. imageBlue.Dispose();
  3505. }
  3506. if (imageGreen != null && !imageGreen.IsDisposed)
  3507. {
  3508. imageGreen.Dispose();
  3509. }
  3510. if (imageRed != null && !imageRed.IsDisposed)
  3511. {
  3512. imageRed.Dispose();
  3513. }
  3514. if (imageContour != null && !imageContour.IsDisposed)
  3515. {
  3516. imageContour.Dispose();
  3517. }
  3518. if (cropContour != null && !cropContour.IsDisposed)
  3519. {
  3520. cropContour.Dispose();
  3521. }
  3522. #endregion
  3523. }
  3524. }
  3525. public class ShuangcengShikeyinzi : AutoMeasureAnalysis
  3526. {
  3527. public DataInfor shangfu = new DataInfor();
  3528. public DataInfor xiafu = new DataInfor();
  3529. public DataInfor tonghou = new DataInfor();
  3530. public DataInfor zonghou = new DataInfor();
  3531. private void Initialize()
  3532. {
  3533. shangfu.name = "上幅";
  3534. shangfu.drawType = "MeasureHLine";
  3535. shangfu.ID = "100172";
  3536. shangfu.aliasName = "ZYLHIA";
  3537. xiafu.name = "下幅";
  3538. xiafu.drawType = "MeasureHLine";
  3539. xiafu.ID = "100173";
  3540. xiafu.aliasName = "KCXVXP";
  3541. tonghou.name = "銅厚";
  3542. tonghou.ID = "100174";
  3543. tonghou.aliasName = "BDJNAX";
  3544. zonghou.name = "縂厚";
  3545. zonghou.ID = "100175";
  3546. zonghou.aliasName = "FQFXCL";
  3547. dataInfors.Add(shangfu);
  3548. dataInfors.Add(xiafu);
  3549. dataInfors.Add(tonghou);
  3550. dataInfors.Add(zonghou);
  3551. number = 4;
  3552. success = 0;
  3553. wrongNumber = number;
  3554. }
  3555. public override void Compute(Mat image, bool isCropFlag, int X, int Y)
  3556. {
  3557. Initialize();
  3558. Ceju ceju = new Ceju();
  3559. Mat[] bgr = Cv2.Split(image);
  3560. Mat imageBlue = bgr[0];
  3561. Mat imageGreen = bgr[1];
  3562. Mat imageRed = bgr[2];
  3563. Mat imageContour = new Mat();
  3564. ceju.GetContour(imageRed, out imageContour);
  3565. //數據提取區域
  3566. int[] dataArea = new int[4];
  3567. ceju.SKYZDataArea(imageContour, out dataArea,isCropFlag);
  3568. Mat cropContour = imageContour[dataArea[0], dataArea[1], dataArea[2], dataArea[3]];
  3569. if (isCropFlag)
  3570. {
  3571. dataArea[0] += Y;
  3572. dataArea[2] += X;
  3573. }
  3574. //提取上幅
  3575. int upperLineValue;
  3576. int[] upperLineOrdinate = new int[3];
  3577. ceju.UpperLine(cropContour, out upperLineValue, out upperLineOrdinate);
  3578. shangfu.Set(upperLineValue, upperLineOrdinate[1] + dataArea[2], upperLineOrdinate[0] + dataArea[0] - 30, upperLineOrdinate[2] + dataArea[2], upperLineOrdinate[0] + dataArea[0] - 30);
  3579. UpdateSuccessLine();
  3580. //提取下幅
  3581. int lowerLineValue = dataArea[3] +X - dataArea[2];
  3582. int[] lowerLineOrdinate = { dataArea[1], dataArea[2], dataArea[3] };
  3583. xiafu.Set(lowerLineValue, lowerLineOrdinate[1], lowerLineOrdinate[0]+Y, lowerLineOrdinate[2]+X, lowerLineOrdinate[0]+Y);
  3584. UpdateSuccessLine();
  3585. //提取縂厚
  3586. int zonghouValue;
  3587. int[] zonghouOrdinate = new int[3];
  3588. ceju.Zonghou(cropContour, out zonghouValue, out zonghouOrdinate);
  3589. zonghou.Set(zonghouValue, zonghouOrdinate[0] + dataArea[2], zonghouOrdinate[1] + dataArea[0], zonghouOrdinate[0] + dataArea[2], zonghouOrdinate[2] + dataArea[0]);
  3590. UpdateSuccessLine();
  3591. //提取銅厚
  3592. Mat cropGreen = imageGreen[dataArea[0], dataArea[1], dataArea[2], dataArea[3]];
  3593. int tonghouoValue;
  3594. int[] tonghouOrdinate = new int[3];
  3595. ceju.Tonghou(cropGreen, cropContour, out tonghouoValue, out tonghouOrdinate);
  3596. tonghou.Set(tonghouoValue, tonghouOrdinate[0] + dataArea[2], tonghouOrdinate[1] + dataArea[0], tonghouOrdinate[0] + dataArea[2], tonghouOrdinate[2] + dataArea[0]);
  3597. UpdateSuccessLine();
  3598. #region
  3599. if (imageBlue != null && !imageBlue.IsDisposed)
  3600. {
  3601. imageBlue.Dispose();
  3602. }
  3603. if (imageGreen != null && !imageGreen.IsDisposed)
  3604. {
  3605. imageGreen.Dispose();
  3606. }
  3607. if (imageRed != null && !imageRed.IsDisposed)
  3608. {
  3609. imageRed.Dispose();
  3610. }
  3611. if (imageContour != null && !imageContour.IsDisposed)
  3612. {
  3613. imageContour.Dispose();
  3614. }
  3615. if (cropContour != null && !cropContour.IsDisposed)
  3616. {
  3617. cropContour.Dispose();
  3618. }
  3619. if (cropGreen != null && !cropGreen.IsDisposed)
  3620. {
  3621. cropGreen.Dispose();
  3622. }
  3623. #endregion
  3624. }
  3625. }
  3626. public class Diegou : AutoMeasureAnalysis
  3627. {
  3628. public DataInfor jiegou1 = new DataInfor();
  3629. public DataInfor jiegou2 = new DataInfor();
  3630. public DataInfor jiegou3 = new DataInfor();
  3631. public DataInfor jiegou4 = new DataInfor();
  3632. public DataInfor jiegou5 = new DataInfor();
  3633. public DataInfor jiegou6 = new DataInfor();
  3634. public DataInfor jiegou7 = new DataInfor();
  3635. public DataInfor jiegou8 = new DataInfor();
  3636. public DataInfor jiegou9 = new DataInfor();
  3637. public DataInfor jiegou10 = new DataInfor();
  3638. public DataInfor jiegou11 = new DataInfor();
  3639. public DataInfor jiegou12 = new DataInfor();
  3640. public DataInfor jiegou13 = new DataInfor();
  3641. public DataInfor jiegou14 = new DataInfor();
  3642. public DataInfor jiegou15 = new DataInfor();
  3643. public DataInfor jiegou16 = new DataInfor();
  3644. public DataInfor jiegou17 = new DataInfor();
  3645. public DataInfor jiegou18 = new DataInfor();
  3646. public DataInfor jiegou19 = new DataInfor();
  3647. public DataInfor jiegou20 = new DataInfor();
  3648. public DataInfor zonghou = new DataInfor();
  3649. private void Initialize()
  3650. {
  3651. jiegou1.name = "曡構1";
  3652. jiegou1.ID = "100212";
  3653. jiegou1.aliasName = "VOIRMJ";
  3654. jiegou2.name = "曡構2";
  3655. jiegou2.ID = "100213";
  3656. jiegou2.aliasName = "AMXAYH";
  3657. jiegou3.name = "曡構3";
  3658. jiegou3.ID = "100214";
  3659. jiegou3.aliasName = "MQJOOW";
  3660. jiegou4.name = "曡構4";
  3661. jiegou4.ID = "100215";
  3662. jiegou4.aliasName = "WSZJJR";
  3663. jiegou5.name = "曡構5";
  3664. jiegou5.ID = "100216";
  3665. jiegou5.aliasName = "KUVUKE";
  3666. jiegou6.name = "曡構6";
  3667. jiegou6.ID = "100217";
  3668. jiegou6.aliasName = "GSAZXR";
  3669. jiegou7.name = "曡構7";
  3670. jiegou7.ID = "100218";
  3671. jiegou7.aliasName = "XTMRAZ";
  3672. jiegou8.name = "曡構8";
  3673. jiegou8.ID = "100219";
  3674. jiegou8.aliasName = "PFVPUY";
  3675. jiegou9.name = "曡構9";
  3676. jiegou9.ID = "100220";
  3677. jiegou9.aliasName = "MMFMAW";
  3678. jiegou10.name = "曡構10";
  3679. jiegou10.ID = "100221";
  3680. jiegou10.aliasName = "AYYCSA";
  3681. jiegou11.name = "曡構11";
  3682. jiegou11.ID = "100222";
  3683. jiegou11.aliasName = "PVPYAV";
  3684. jiegou12.name = "曡構12";
  3685. jiegou12.ID = "100223";
  3686. jiegou12.aliasName = "VEBMCK";
  3687. jiegou13.name = "曡構13";
  3688. jiegou13.ID = "100224";
  3689. jiegou13.aliasName = "JXSFKM";
  3690. jiegou14.name = "曡構14";
  3691. jiegou14.ID = "100225";
  3692. jiegou14.aliasName = "VRABGP";
  3693. jiegou15.name = "曡構15";
  3694. jiegou15.ID = "100226";
  3695. jiegou15.aliasName = "EQRTBR";
  3696. jiegou16.name = "曡構16";
  3697. jiegou16.ID = "100227";
  3698. jiegou16.aliasName = "JKGYMV";
  3699. jiegou17.name = "曡構17";
  3700. jiegou17.ID = "100228";
  3701. jiegou17.aliasName = "JXYZFG";
  3702. jiegou18.name = "曡構18";
  3703. jiegou18.ID = "100229";
  3704. jiegou18.aliasName = "XFFJQH";
  3705. jiegou19.name = "曡構19";
  3706. jiegou19.ID = "100230";
  3707. jiegou19.aliasName = "HTHMIC";
  3708. jiegou20.name = "曡構20";
  3709. jiegou20.ID = "100231";
  3710. jiegou20.aliasName = "WKNIGJ";
  3711. zonghou.name = "縂厚";
  3712. zonghou.ID = "100211";
  3713. zonghou.aliasName = "JIUHDG";
  3714. dataInfors.Add(jiegou1);
  3715. dataInfors.Add(jiegou2);
  3716. dataInfors.Add(jiegou3);
  3717. dataInfors.Add(jiegou4);
  3718. dataInfors.Add(jiegou5);
  3719. dataInfors.Add(jiegou6);
  3720. dataInfors.Add(jiegou7);
  3721. dataInfors.Add(jiegou8);
  3722. dataInfors.Add(jiegou9);
  3723. dataInfors.Add(jiegou10);
  3724. dataInfors.Add(jiegou11);
  3725. dataInfors.Add(jiegou12);
  3726. dataInfors.Add(jiegou13);
  3727. dataInfors.Add(jiegou14);
  3728. dataInfors.Add(jiegou15);
  3729. dataInfors.Add(jiegou16);
  3730. dataInfors.Add(jiegou17);
  3731. dataInfors.Add(jiegou18);
  3732. dataInfors.Add(jiegou19);
  3733. dataInfors.Add(jiegou20);
  3734. dataInfors.Add(zonghou);
  3735. number = 20;
  3736. success = 0;
  3737. wrongNumber = number;
  3738. }
  3739. public override void Compute(Mat image, bool isCropFlag, int X, int Y)
  3740. {
  3741. Initialize();
  3742. Ceju ceju = new Ceju();
  3743. int upper = 0;
  3744. int border = 0;
  3745. if (isCropFlag)
  3746. {
  3747. upper = Y;
  3748. border = X;
  3749. }
  3750. int centerA = 0;
  3751. int width = 200;
  3752. if (image.Width > 200)
  3753. {
  3754. centerA = image.Width / 2 - 100;
  3755. width = 200;
  3756. }
  3757. else
  3758. {
  3759. centerA = 0;
  3760. width = image.Width;
  3761. }
  3762. Mat gray = image.Clone().CvtColor(ColorConversionCodes.BGR2GRAY);
  3763. //Cv2.ImWrite(@"C:\Users\54434\Desktop\gray.jpg", gray);
  3764. if (daodianbu && DieGouTools.CalcEnhanceFlag(gray))
  3765. {
  3766. //gray = Tools.ShadingCorrection(gray);
  3767. gray = BinaryTools.BCGTransferFunction(gray);
  3768. }
  3769. Mat tempa = new Mat(gray, new Rect(centerA, 0, width, gray.Height));
  3770. Mat grayToDebug = gray.Clone();
  3771. int mean = (int)(tempa.Mean());
  3772. List<float> fl = new List<float>();
  3773. for (int h = 0; h < tempa.Height - 1; h++)
  3774. {
  3775. int a_sum = (int)(tempa.Row[h].Sum());
  3776. int b_sum = (int)(tempa.Row[h + 1].Sum());
  3777. float v = Math.Abs(a_sum * 1f * 10000 / b_sum - 10000);
  3778. fl.Add(v < 250 ? 0 : v);
  3779. }
  3780. int[] hist_int = HistTools.Smooth(fl.ToArray(), 5, fl.Count);
  3781. List<int> mountainsList = new List<int>();
  3782. List<int[]> mountainsArrList = new List<int[]>();
  3783. List<int[]> mountainsArrListBackUp = new List<int[]>();
  3784. Tools.FindTopAndBetweenWithOutWT123(hist_int, 0, hist_int.Length, mountainsList, mountainsArrList, mountainsArrListBackUp, new List<string>(), 15);
  3785. mountainsList.Sort();
  3786. if (!mountainsList.Contains(0)) mountainsList.Insert(0, 0);
  3787. if (!mountainsList.Contains(gray.Height)) mountainsList.Add(gray.Height);
  3788. List<int> SplitListA = new List<int>();
  3789. for (int i = 0; i < mountainsList.Count-1; i++)
  3790. {
  3791. if (mountainsList[i + 1] - mountainsList[i] < 110)
  3792. {
  3793. continue;
  3794. }
  3795. //截取中间的,进行再次寻找
  3796. Mat temp1 = new Mat(gray, new Rect(centerA, mountainsList[i], width, mountainsList[i + 1] - mountainsList[i]));
  3797. grayToDebug.Rectangle(new Rect(centerA, mountainsList[i], width, mountainsList[i + 1] - mountainsList[i]), new Scalar(255));
  3798. //Cv2.ImWrite(@"C:\Users\54434\Desktop\temp1_" + i + ".jpg", temp1);
  3799. //Mat thresh1 = new Mat();
  3800. ////二值化
  3801. Mat thresh1 = temp1.Threshold(mean > 85 ? 200 : 80, 1/*255*/, ThresholdTypes.Binary);
  3802. ////Cv2.Threshold(temp1, thresh1, 0, 1/*255*/, ThresholdTypes.Otsu);
  3803. //thresh1 = 1/*255*/ - thresh1;
  3804. //Cv2.ImWrite(@"C:\Users\54434\Desktop\tthresh1_" + i + ".jpg", thresh1 * 255);
  3805. //Mat thresh1 = 1 - filter.Threshold(0, 1, ThresholdTypes.Otsu);// 二值化
  3806. Mat seOpen1 = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(15, 1/*水平线<--3, 3*/));// 开运算
  3807. Mat open1 = new Mat();
  3808. //OpenCV提取图像中的垂直线(或者水平线) 定义结构元素,开操作
  3809. Cv2.MorphologyEx(thresh1, open1, MorphTypes.Open, seOpen1);
  3810. //Cv2.ImWrite(@"C:\Users\54434\Desktop\open1\_" + i + ".jpg", open1 * 255/*open1 * 127*/);
  3811. //Cv2.ImWrite(@"C:\Users\54434\Desktop\temp1Otsu.jpg", temp1Otsu);
  3812. int threshold = mean > 85 ? 200 : 80;
  3813. List<float> f2 = new List<float>();
  3814. for (int h = 0; h < temp1.Height - 1; h++)
  3815. {
  3816. if (h < 10 || h > temp1.Height - 10)
  3817. {
  3818. f2.Add(0);
  3819. continue;
  3820. }
  3821. int a_sum = (int)(temp1.Row[h].Sum());
  3822. int b_sum = (int)(temp1.Row[h + 1].Sum());
  3823. float v = Math.Abs(a_sum * 1f * 10000 / b_sum - 10000);
  3824. f2.Add(v < threshold ? 0 : v);
  3825. }
  3826. int[] hist_int_1 = HistTools.Smooth(f2.ToArray(), 10, f2.Count);
  3827. List<int> mountainsList_1 = new List<int>();
  3828. List<int[]> mountainsArrList_1 = new List<int[]>();
  3829. List<int[]> mountainsArrListBackUp_1 = new List<int[]>();
  3830. Tools.FindTopAndBetweenWithOutWT123(hist_int_1, 0, hist_int_1.Length, mountainsList_1, mountainsArrList_1, mountainsArrListBackUp_1, new List<string>(), 15);
  3831. for (int h = mountainsList_1.Count - 1; h >= 0; h--)
  3832. {
  3833. if (h > 0)
  3834. {
  3835. if (daodianbu || Math.Abs(mountainsList_1[h] - mountainsList_1[h - 1]) > 20)
  3836. {
  3837. continue;
  3838. }
  3839. mountainsList_1.RemoveAt(h);
  3840. }
  3841. }
  3842. int temp_v = daodianbu ? 10 : 15;
  3843. for (int a = 0; a < mountainsList_1.Count; a++)
  3844. {
  3845. mountainsList_1[a] += mountainsList[i];
  3846. if (mean >= 65)
  3847. {
  3848. if (Math.Abs(mountainsList_1[a] - mountainsList[i]) > temp_v && Math.Abs(mountainsList_1[a] - mountainsList[i + 1]) > temp_v
  3849. //&& /*true && 1(46) 1(105) 1(114) 有改善 去掉了几个没用的分割点*/ open1.At<byte>(Math.Max(0, mountainsList_1[a] - mountainsList[i] - 2), width / 2) == 0
  3850. //&& /*true && */ open1[startI, endI, 0, open1.Cols - 1].Sum().At<byte>(Math.Max(0, mountainsList_1[a] - mountainsList[i] - 2), width / 2) == 0
  3851. )
  3852. {
  3853. int startI = Math.Max(0, mountainsList_1[a] - mountainsList[i] - 1);
  3854. int endI = Math.Min(startI + 1, open1.Rows - 1);
  3855. if (true && (endI < startI || (int)open1[startI, endI, 0, open1.Cols - 1].Sum() == 0
  3856. || (endI < open1.Rows - 1 && (int)open1[startI + 1, endI + 1, 0, open1.Cols - 1].Sum() == 0)
  3857. || (endI < open1.Rows - 2 && (int)open1[startI + 2, endI + 2, 0, open1.Cols - 1].Sum() == 0)
  3858. || (endI < open1.Rows - 3 && (int)open1[startI + 3, endI + 3, 0, open1.Cols - 1].Sum() == 0)
  3859. || (endI < open1.Rows - 4 && (int)open1[startI + 4, endI + 4, 0, open1.Cols - 1].Sum() == 0)))
  3860. //int loopT = -3;
  3861. //while (++loopT < 3)
  3862. //{
  3863. // int startI = Math.Max(0, mountainsList_1[a] + loopT - mountainsList[i] - 2);
  3864. // int endI = Math.Min(startI + 5, open1.Rows - 1);
  3865. // if (endI > startI && (int)open1[startI, endI, 0, open1.Cols - 1].Sum() > /*255 * */open1.Cols)
  3866. // {
  3867. // SplitListA.Add(mountainsList_1[a]);
  3868. // break;
  3869. // }
  3870. // else
  3871. // {
  3872. // if (endI > startI)
  3873. // {
  3874. // Console.WriteLine("Sum_" + i + ":" + (int)open1[startI, endI, 0, open1.Cols - 1].Sum()
  3875. // + "|" + open1.Cols);
  3876. // }
  3877. // else
  3878. // Console.WriteLine("Sum_" + i + ":startI" + startI
  3879. // + "|" + endI);
  3880. // //SplitListA.Add(mountainsList_1[a]);
  3881. // }
  3882. //}
  3883. //if (loopT == 3)
  3884. {
  3885. SplitListA.Add(mountainsList_1[a]);
  3886. //Cv2.ImWrite(@"C:\Users\54434\Desktop\tthresh1_" + i + ".jpg", thresh1 * 255);
  3887. //Cv2.ImWrite(@"C:\Users\54434\Desktop\open1_" + i + ".jpg", open1 * 255);
  3888. }
  3889. //int startI = Math.Max(0, mountainsList_1[a]- mountainsList[i] - 2);
  3890. //int endI = Math.Min(startI + 5, open1.Rows - 1);
  3891. //if (endI > startI && (int)open1[startI, endI, 0, open1.Cols - 1].Sum() > /*255 * */open1.Cols)
  3892. //{
  3893. // SplitListA.Add(mountainsList_1[a]);
  3894. //}
  3895. //else
  3896. //{
  3897. // if (endI > startI)
  3898. // {
  3899. // Cv2.ImWrite(@"C:\Users\54434\Desktop\tthresh1_" + i + ".jpg", thresh1 * 255);
  3900. // Cv2.ImWrite(@"C:\Users\54434\Desktop\open1_" + i + ".jpg", open1 * 255);
  3901. // Console.WriteLine("Sum_" + i + ":" + (int)open1[startI, endI, 0, open1.Cols - 1].Sum()
  3902. // + "|" + open1.Cols);
  3903. // }
  3904. // else
  3905. // Console.WriteLine("Sum_" + i + ":startI" + startI
  3906. // + "|" + endI);
  3907. // //SplitListA.Add(mountainsList_1[a]);
  3908. //}
  3909. ////Scalar sum = open1[startI, , 0, open1.Cols - 1].Sum();
  3910. //////if (255 * open1.Cols/*30*/ < (int)sum)
  3911. ////SplitListA.Add(mountainsList_1[a]);
  3912. }
  3913. }
  3914. else
  3915. {
  3916. SplitListA.Add(mountainsList_1[a]);
  3917. }
  3918. }
  3919. if(daodianbu && mountainsList_1.Count==0)
  3920. {
  3921. }
  3922. if (temp1 != null && !temp1.IsDisposed) temp1.Dispose();
  3923. #region[释放内存]
  3924. if (thresh1 != null && !thresh1.IsDisposed)
  3925. {
  3926. thresh1.Dispose();
  3927. }
  3928. if (temp1 != null && !temp1.IsDisposed)
  3929. {
  3930. temp1.Dispose();
  3931. }
  3932. if (open1 != null && !open1.IsDisposed)
  3933. {
  3934. open1.Dispose();
  3935. }
  3936. if (seOpen1 != null && !seOpen1.IsDisposed)
  3937. {
  3938. seOpen1.Dispose();
  3939. }
  3940. #endregion
  3941. }
  3942. //Cv2.ImWrite(@"C:\Users\54434\Desktop\grayToDebug.jpg", grayToDebug);
  3943. List<int> SplitListB = new List<int>();
  3944. SplitListB.AddRange(mountainsList);
  3945. SplitListB.AddRange(SplitListA);
  3946. SplitListB.Sort();
  3947. //第一次过滤
  3948. for (int h = SplitListB.Count - 2; h >= 1; h--)
  3949. {
  3950. if (SplitListB[h + 1] - SplitListB[h] < 30 && SplitListB[h] - SplitListB[h - 1] < 30)
  3951. {
  3952. SplitListB.RemoveAt(h);
  3953. }
  3954. }
  3955. int firstHeight = 30;
  3956. if (daodianbu)
  3957. {
  3958. firstHeight = 10;
  3959. }
  3960. //第二次过滤
  3961. for (int h = SplitListB.Count - 1; h >= 0; h--)
  3962. {
  3963. if (SplitListB[h] > gray.Height - firstHeight || SplitListB[h] < firstHeight)
  3964. {
  3965. SplitListB.RemoveAt(h);
  3966. continue;
  3967. }
  3968. if (h > 0)
  3969. {
  3970. if (Math.Abs(SplitListB[h] - SplitListB[h - 1]) > firstHeight)
  3971. {
  3972. continue;
  3973. }
  3974. SplitListB.RemoveAt(h);
  3975. }
  3976. }
  3977. //第三次过滤
  3978. for (int h = SplitListB.Count - 1; h >= 0; h--)
  3979. {
  3980. int mean_v = (int)(gray.Row[SplitListB[h]].Mean());
  3981. if (mean_v < 80)
  3982. {
  3983. Mat temp1 = new Mat(gray, new Rect(centerA, 0, width, gray.Height - 1));
  3984. int top = SplitListB[h] - 5;
  3985. int bottom = SplitListB[h] + 5;
  3986. if (top < 0) top = 0;
  3987. if (bottom > gray.Height - 1) bottom = gray.Height - 1;
  3988. List<int> list = new List<int>();
  3989. for (int v = top; v < bottom; v++)
  3990. {
  3991. list.Add((int)(temp1.Row[v].Sum()));
  3992. }
  3993. if ((list.Max() * 1f * 10000 / list.Min()) - 10000 < 250)
  3994. {
  3995. SplitListB.RemoveAt(h);
  3996. }
  3997. if (temp1 != null && !temp1.IsDisposed) temp1.Dispose();
  3998. #region[释放内存]
  3999. if (temp1 != null && !temp1.IsDisposed)
  4000. {
  4001. temp1.Dispose();
  4002. }
  4003. #endregion
  4004. }
  4005. }
  4006. //最后容错
  4007. if (SplitListB.Count > 20)
  4008. {
  4009. for (int h = SplitListB.Count - 1; h >= 0; h--)
  4010. {
  4011. if (h > 20)
  4012. SplitListB.RemoveAt(h);
  4013. }
  4014. }
  4015. int middle = gray.Cols / 2;
  4016. for (int i = 0; i < SplitListB.Count - 1; i++)
  4017. {
  4018. if (i <= 100)
  4019. {
  4020. dataInfors[i].Set(SplitListB[i + 1] - SplitListB[i], middle + border, SplitListB[i] + upper, middle + border, SplitListB[i + 1] + upper);
  4021. }
  4022. UpdateSuccessLine();
  4023. }
  4024. dataInfors[20].Set(SplitListB[SplitListB.Count - 1] - SplitListB[0], middle + 300 + border, SplitListB[0] + upper, middle + 300 + border, SplitListB[SplitListB.Count - 1] + upper);
  4025. UpdateSuccessLine();
  4026. if (gray != null && !gray.IsDisposed) gray.Dispose();
  4027. if (tempa != null && !tempa.IsDisposed) gray.Dispose();
  4028. #region[释放内存]
  4029. if (gray != null && !gray.IsDisposed)
  4030. {
  4031. gray.Dispose();
  4032. }
  4033. if (tempa != null && !tempa.IsDisposed)
  4034. {
  4035. tempa.Dispose();
  4036. }
  4037. if (grayToDebug != null && !grayToDebug.IsDisposed)
  4038. {
  4039. grayToDebug.Dispose();
  4040. }
  4041. #endregion
  4042. System.GC.Collect();
  4043. }
  4044. }
  4045. public class Diegou_Bak : AutoMeasureAnalysis
  4046. {
  4047. public DataInfor jiegou1 = new DataInfor();
  4048. public DataInfor jiegou2 = new DataInfor();
  4049. public DataInfor jiegou3 = new DataInfor();
  4050. public DataInfor jiegou4 = new DataInfor();
  4051. public DataInfor jiegou5 = new DataInfor();
  4052. public DataInfor jiegou6 = new DataInfor();
  4053. public DataInfor jiegou7 = new DataInfor();
  4054. public DataInfor jiegou8 = new DataInfor();
  4055. public DataInfor jiegou9 = new DataInfor();
  4056. public DataInfor jiegou10 = new DataInfor();
  4057. public DataInfor jiegou11 = new DataInfor();
  4058. public DataInfor jiegou12 = new DataInfor();
  4059. public DataInfor jiegou13 = new DataInfor();
  4060. public DataInfor jiegou14 = new DataInfor();
  4061. public DataInfor jiegou15 = new DataInfor();
  4062. public DataInfor jiegou16 = new DataInfor();
  4063. public DataInfor jiegou17 = new DataInfor();
  4064. public DataInfor jiegou18 = new DataInfor();
  4065. public DataInfor jiegou19 = new DataInfor();
  4066. public DataInfor jiegou20 = new DataInfor();
  4067. public DataInfor zonghou = new DataInfor();
  4068. private void Initialize()
  4069. {
  4070. jiegou1.name = "曡構1";
  4071. jiegou1.ID = "100212";
  4072. jiegou1.aliasName = "VOIRMJ";
  4073. jiegou2.name = "曡構2";
  4074. jiegou2.ID = "100213";
  4075. jiegou2.aliasName = "AMXAYH";
  4076. jiegou3.name = "曡構3";
  4077. jiegou3.ID = "100214";
  4078. jiegou3.aliasName = "MQJOOW";
  4079. jiegou4.name = "曡構4";
  4080. jiegou4.ID = "100215";
  4081. jiegou4.aliasName = "WSZJJR";
  4082. jiegou5.name = "曡構5";
  4083. jiegou5.ID = "100216";
  4084. jiegou5.aliasName = "KUVUKE";
  4085. jiegou6.name = "曡構6";
  4086. jiegou6.ID = "100217";
  4087. jiegou6.aliasName = "GSAZXR";
  4088. jiegou7.name = "曡構7";
  4089. jiegou7.ID = "100218";
  4090. jiegou7.aliasName = "XTMRAZ";
  4091. jiegou8.name = "曡構8";
  4092. jiegou8.ID = "100219";
  4093. jiegou8.aliasName = "PFVPUY";
  4094. jiegou9.name = "曡構9";
  4095. jiegou9.ID = "100220";
  4096. jiegou9.aliasName = "MMFMAW";
  4097. jiegou10.name = "曡構10";
  4098. jiegou10.ID = "100221";
  4099. jiegou10.aliasName = "AYYCSA";
  4100. jiegou11.name = "曡構11";
  4101. jiegou11.ID = "100222";
  4102. jiegou11.aliasName = "PVPYAV";
  4103. jiegou12.name = "曡構12";
  4104. jiegou12.ID = "100223";
  4105. jiegou12.aliasName = "VEBMCK";
  4106. jiegou13.name = "曡構13";
  4107. jiegou13.ID = "100224";
  4108. jiegou13.aliasName = "JXSFKM";
  4109. jiegou14.name = "曡構14";
  4110. jiegou14.ID = "100225";
  4111. jiegou14.aliasName = "VRABGP";
  4112. jiegou15.name = "曡構15";
  4113. jiegou15.ID = "100226";
  4114. jiegou15.aliasName = "EQRTBR";
  4115. jiegou16.name = "曡構16";
  4116. jiegou16.ID = "100227";
  4117. jiegou16.aliasName = "JKGYMV";
  4118. jiegou17.name = "曡構17";
  4119. jiegou17.ID = "100228";
  4120. jiegou17.aliasName = "JXYZFG";
  4121. jiegou18.name = "曡構18";
  4122. jiegou18.ID = "100229";
  4123. jiegou18.aliasName = "XFFJQH";
  4124. jiegou19.name = "曡構19";
  4125. jiegou19.ID = "100230";
  4126. jiegou19.aliasName = "HTHMIC";
  4127. jiegou20.name = "曡構20";
  4128. jiegou20.ID = "100231";
  4129. jiegou20.aliasName = "WKNIGJ";
  4130. zonghou.name = "縂厚";
  4131. zonghou.ID = "100211";
  4132. zonghou.aliasName = "JIUHDG";
  4133. dataInfors.Add(jiegou1);
  4134. dataInfors.Add(jiegou2);
  4135. dataInfors.Add(jiegou3);
  4136. dataInfors.Add(jiegou4);
  4137. dataInfors.Add(jiegou5);
  4138. dataInfors.Add(jiegou6);
  4139. dataInfors.Add(jiegou7);
  4140. dataInfors.Add(jiegou8);
  4141. dataInfors.Add(jiegou9);
  4142. dataInfors.Add(jiegou10);
  4143. dataInfors.Add(jiegou11);
  4144. dataInfors.Add(jiegou12);
  4145. dataInfors.Add(jiegou13);
  4146. dataInfors.Add(jiegou14);
  4147. dataInfors.Add(jiegou15);
  4148. dataInfors.Add(jiegou16);
  4149. dataInfors.Add(jiegou17);
  4150. dataInfors.Add(jiegou18);
  4151. dataInfors.Add(jiegou19);
  4152. dataInfors.Add(jiegou20);
  4153. dataInfors.Add(zonghou);
  4154. number = 20;
  4155. success = 0;
  4156. wrongNumber = number;
  4157. }
  4158. public override void Compute(Mat image, bool isCropFlag, int X, int Y)
  4159. {
  4160. Initialize();
  4161. Ceju ceju = new Ceju();
  4162. int upper = 0;
  4163. int border = 0;
  4164. if (isCropFlag)
  4165. {
  4166. upper = Y;
  4167. border = X;
  4168. }
  4169. Mat[] bgr = Cv2.Split(image);
  4170. Mat imageBlue = bgr[0];
  4171. Mat imageGreen = bgr[1];
  4172. Mat imageRed = bgr[2];
  4173. Mat gray = new Mat();
  4174. Cv2.CvtColor(image, gray, ColorConversionCodes.BGR2GRAY);
  4175. List<int> ordinates = new List<int>();
  4176. #region //分类
  4177. if (daodianbu)//有导电布
  4178. {
  4179. //判断铜数
  4180. int tongshu = 0;
  4181. int tonghou = 0;
  4182. int jianhou = 0;
  4183. ceju.GetTongCengShuliang(gray, out tongshu, out tonghou, out jianhou);
  4184. //MessageBox.Show(tongshu.ToString());
  4185. if (tongshu == 1)//只有一层铜
  4186. {
  4187. ceju.DaoidanbuDanceng(gray, out ordinates);
  4188. }
  4189. else if (tongshu == 2)//有两层铜
  4190. {
  4191. int zonghou = 0;
  4192. ceju.DiegouGetZonghou(gray, out zonghou);
  4193. if (zonghou < 500)//上下总厚窄时
  4194. {
  4195. ceju.DaoidanbuDanceng(gray, out ordinates);
  4196. }
  4197. else//上下总厚宽时
  4198. {
  4199. ceju.DaodianbuShuangcengZongHou(gray, out ordinates);
  4200. }
  4201. }
  4202. else//有三层铜时
  4203. {
  4204. ceju.DaodianbuSanceng(gray, out ordinates);
  4205. }
  4206. }
  4207. else//无导电布
  4208. {
  4209. //判断铜数
  4210. int tongshu = 0;
  4211. int tonghou = 0;
  4212. int jianhou = 0;
  4213. ceju.GetTongCengShuliang(gray, out tongshu, out tonghou, out jianhou);
  4214. //MessageBox.Show(tongshu.ToString());
  4215. if (tongshu == 1)//铜层一层的时候
  4216. {
  4217. if (tonghou > 150)//一层里面层厚大的情况
  4218. {
  4219. ceju.WuDaodianbuDancengHou(gray, out ordinates);
  4220. }
  4221. else//窄的时候
  4222. {
  4223. int zonghou = 0;
  4224. ceju.DiegouGetZonghou2(gray, out zonghou);
  4225. if (zonghou < 300)//总厚小的时候,较亮图
  4226. {
  4227. ceju.WuDaodianbuDancengZhaiZonghouZhai(gray, out ordinates);
  4228. }
  4229. else //总厚大的时候,较暗图
  4230. {
  4231. ceju.WuDaodianbuDancengZhaiZonghouKuan(gray, out ordinates);
  4232. }
  4233. }
  4234. }
  4235. else if (tongshu == 2)//铜层两层的时候
  4236. {
  4237. if (tonghou > 150)//铜层厚较大时
  4238. {
  4239. ceju.WuDaodianbuShuangcengCenghou(gray, out ordinates);
  4240. }
  4241. else if (tonghou > 100)//铜层厚中等大小,需要测量内部线,7层铜
  4242. {
  4243. ceju.WuDaodianbuQicengtong(gray, out ordinates);
  4244. }
  4245. else
  4246. {
  4247. int zonghou = 0;
  4248. ceju.DiegouGetZonghou(gray, out zonghou);
  4249. if (tonghou > 50 && zonghou > 800 && jianhou > 100)
  4250. {
  4251. ceju.WudaodianbuShuangcengD(gray, out ordinates);
  4252. }
  4253. else
  4254. {
  4255. ceju.WudaodianbuShuangcengQita(gray, out ordinates);
  4256. }
  4257. }
  4258. }
  4259. else if (tongshu == 3)//铜层三层的时候
  4260. {
  4261. ceju.WudaodianbuSanceng(gray, out ordinates);
  4262. }
  4263. else if (tongshu == 4)//铜层四层的时候
  4264. {
  4265. ceju.WuDaodianbuSiceng(gray, out ordinates);
  4266. }
  4267. }
  4268. #endregion
  4269. //标记红线
  4270. //for (int i = 0; i < ordinates.Count; i++)
  4271. //{
  4272. // ceju.LineShow(image, 0, ordinates[i], image.Cols - 1, ordinates[i]);
  4273. //}
  4274. //ceju.ImageShow(image);
  4275. //计算线条
  4276. //for (int i = 0; i < ordinates.Count - 1; i++)
  4277. //{
  4278. // DataInfor dataInfor = new DataInfor();
  4279. // dataInfor.Set(ordinates[i + 1] - ordinates[i], image.Cols / 2 + border, ordinates[i] + upper, image.Cols / 2 + border, ordinates[i + 1] + upper);
  4280. // dataInfors.Add(dataInfor);
  4281. //}
  4282. //zonghou.Set(ordinates[ordinates.Count - 1] - ordinates[0], image.Cols / 2 + 300 + border, ordinates[0] + upper, image.Cols / 2 + 300 + border, ordinates[ordinates.Count - 1] + upper);
  4283. //dataInfors.Add(zonghou);
  4284. int middle = image.Cols / 2;
  4285. for (int i = 0; i < ordinates.Count - 1; i++)
  4286. {
  4287. if (i <= 19)
  4288. {
  4289. dataInfors[i].Set(ordinates[i + 1] - ordinates[i], middle + border, ordinates[i] + upper, middle + border, ordinates[i + 1] + upper);
  4290. }
  4291. UpdateSuccessLine();
  4292. }
  4293. dataInfors[20].Set(ordinates[ordinates.Count - 1] - ordinates[0], middle + 300 + border, ordinates[0] + upper, middle + 300 + border, ordinates[ordinates.Count - 1] + upper);
  4294. UpdateSuccessLine();
  4295. //dataInfors.Add(zonghou);
  4296. #region[释放内存]
  4297. if (imageBlue != null && !imageBlue.IsDisposed)
  4298. {
  4299. imageBlue.Dispose();
  4300. }
  4301. if (imageGreen != null && !imageGreen.IsDisposed)
  4302. {
  4303. imageGreen.Dispose();
  4304. }
  4305. if (imageRed != null && !imageRed.IsDisposed)
  4306. {
  4307. imageRed.Dispose();
  4308. }
  4309. #endregion
  4310. }
  4311. }
  4312. /// <summary>
  4313. /// 锡膏
  4314. /// </summary>
  4315. public class Xigao : AutoMeasureAnalysis
  4316. {
  4317. public DataInfor leftShang = new DataInfor();
  4318. public DataInfor leftXia = new DataInfor();
  4319. public DataInfor rightShang = new DataInfor();
  4320. public DataInfor rightXia = new DataInfor();
  4321. private void Initialize()
  4322. {
  4323. leftShang.name = "左上";
  4324. leftShang.ID = "100301";
  4325. leftShang.aliasName = "MCNUUR";
  4326. leftXia.name = "左下";
  4327. leftXia.ID = "100302";
  4328. leftXia.aliasName = "QHFLCT";
  4329. rightShang.name = "右上";
  4330. rightShang.ID = "100303";
  4331. rightShang.aliasName = "LNGTUH";
  4332. rightXia.name = "右下";
  4333. rightXia.ID = "100304";
  4334. rightXia.aliasName = "YGCSHP";
  4335. dataInfors.Add(leftShang);
  4336. dataInfors.Add(leftXia);
  4337. dataInfors.Add(rightShang);
  4338. dataInfors.Add(rightXia);
  4339. }
  4340. public void Compute1(Mat image, bool isCropFlag, int X, int Y)
  4341. {
  4342. Initialize();
  4343. Ceju ceju = new Ceju();
  4344. int upper = 0;
  4345. int border = 0;
  4346. if (isCropFlag)
  4347. {
  4348. upper = Y;
  4349. border = X;
  4350. }
  4351. Mat[] bgr = Cv2.Split(image);
  4352. Mat imageRed = bgr[2];
  4353. Mat gray = image.CvtColor(ColorConversionCodes.BGR2GRAY);
  4354. //红色通道增强后图片
  4355. Mat imageRedPointEnhancement = new Mat();
  4356. ceju.PointEnhancement(gray, out imageRedPointEnhancement);
  4357. //获取二值图
  4358. Mat contour = new Mat();
  4359. Mat contourFill = new Mat();
  4360. double t1 = Cv2.Threshold(imageRed, contour, 0, 1, ThresholdTypes.Otsu);
  4361. ceju.Fill(contour, out contourFill, 1);
  4362. int[] leftShangOrdinates = new int[3];
  4363. int[] rightShangOrdinates = new int[3];
  4364. int[] leftXiaOrdinates = new int[3];
  4365. int[] rightXiaOrdinates = new int[3];
  4366. //获取四个纵坐标,一个横坐标
  4367. ceju.GetXigaoArea(contour, out int[] dataArea, out int start);
  4368. //判断方向
  4369. int[] zuidalie = new int[2];
  4370. bool cunzai;
  4371. int lowrow;
  4372. ceju.youCexiangsu(contour, out cunzai, out lowrow, out zuidalie, dataArea);
  4373. if (cunzai)//開口向内
  4374. {
  4375. ceju.XigaoKaikouXiangnei(gray, dataArea, start, out leftShangOrdinates, out rightShangOrdinates, out leftXiaOrdinates, out rightXiaOrdinates);
  4376. //標注
  4377. leftShang.Set(leftShangOrdinates[2] - leftShangOrdinates[1], leftShangOrdinates[0] + border, leftShangOrdinates[1] + upper, leftShangOrdinates[0] + border, leftShangOrdinates[2] + upper);
  4378. leftXia.Set(leftXiaOrdinates[2] - leftXiaOrdinates[1], leftXiaOrdinates[0] + border, leftXiaOrdinates[1] + upper, leftXiaOrdinates[0] + border, leftXiaOrdinates[2] + upper);
  4379. rightShang.Set(rightShangOrdinates[2] - rightShangOrdinates[1], rightShangOrdinates[0] + border, rightShangOrdinates[1] + upper, rightShangOrdinates[0] + border, rightShangOrdinates[2] + upper);
  4380. rightXia.Set(rightXiaOrdinates[2] - rightXiaOrdinates[1], rightXiaOrdinates[0] + border, rightXiaOrdinates[1] + upper, rightXiaOrdinates[0] + border, rightXiaOrdinates[2] + upper);
  4381. }
  4382. else//開口向外
  4383. {
  4384. //判断正向黑块是否突出
  4385. bool tuChu;
  4386. int[] Hang = new int[2];
  4387. ceju.Heikuai3(gray, start, dataArea, out tuChu);
  4388. if (tuChu)//黑塊有突出
  4389. {
  4390. ceju.XigaoYouheikuai(gray, dataArea, start, out leftShangOrdinates, out rightShangOrdinates, out leftXiaOrdinates, out rightXiaOrdinates);
  4391. //標注
  4392. leftShang.Set(leftShangOrdinates[2] - leftShangOrdinates[1], leftShangOrdinates[0] + border, leftShangOrdinates[1] + upper, leftShangOrdinates[0] + border, leftShangOrdinates[2] + upper);
  4393. leftXia.Set(leftXiaOrdinates[2] - leftXiaOrdinates[1], leftXiaOrdinates[0] + border, leftXiaOrdinates[1] + upper, leftXiaOrdinates[0] + border, leftXiaOrdinates[2] + upper);
  4394. rightShang.Set(rightShangOrdinates[2] - rightShangOrdinates[1], rightShangOrdinates[0] + border, rightShangOrdinates[1] + upper, rightShangOrdinates[0] + border, rightShangOrdinates[2] + upper);
  4395. rightXia.Set(rightXiaOrdinates[2] - rightXiaOrdinates[1], rightXiaOrdinates[0] + border, rightXiaOrdinates[1] + upper, rightXiaOrdinates[0] + border, rightXiaOrdinates[2] + upper);
  4396. }
  4397. else
  4398. {
  4399. ceju.WanQu2(gray, out bool wanQu, dataArea, start, out int[] a);
  4400. if (wanQu)//向上弯
  4401. {
  4402. ceju.XigaoXiangShangWanqu(gray, dataArea, start, out leftShangOrdinates, out rightShangOrdinates, out leftXiaOrdinates, out rightXiaOrdinates);
  4403. //標注
  4404. leftShang.Set(leftShangOrdinates[2] - leftShangOrdinates[1], leftShangOrdinates[0] + border, leftShangOrdinates[1] + upper, leftShangOrdinates[0] + border, leftShangOrdinates[2] + upper);
  4405. leftXia.Set(leftXiaOrdinates[2] - leftXiaOrdinates[1], leftXiaOrdinates[0] + border, leftXiaOrdinates[1] + upper, leftXiaOrdinates[0] + border, leftXiaOrdinates[2] + upper);
  4406. rightShang.Set(rightShangOrdinates[2] - rightShangOrdinates[1], rightShangOrdinates[0] + border, rightShangOrdinates[1] + upper, rightShangOrdinates[0] + border, rightShangOrdinates[2] + upper);
  4407. rightXia.Set(rightXiaOrdinates[2] - rightXiaOrdinates[1], rightXiaOrdinates[0] + border, rightXiaOrdinates[1] + upper, rightXiaOrdinates[0] + border, rightXiaOrdinates[2] + upper);
  4408. }
  4409. else//向下弯
  4410. {
  4411. ceju.XigaoXiangXiaWanqu(gray, dataArea, start, out leftShangOrdinates, out rightShangOrdinates, out leftXiaOrdinates, out rightXiaOrdinates);
  4412. //標注
  4413. leftShang.Set(leftShangOrdinates[2] - leftShangOrdinates[1], leftShangOrdinates[0] + border, leftShangOrdinates[1] + upper, leftShangOrdinates[0] + border, leftShangOrdinates[2] + upper);
  4414. leftXia.Set(leftXiaOrdinates[2] - leftXiaOrdinates[1], leftXiaOrdinates[0] + border, leftXiaOrdinates[1] + upper, leftXiaOrdinates[0] + border, leftXiaOrdinates[2] + upper);
  4415. rightShang.Set(rightShangOrdinates[2] - rightShangOrdinates[1], rightShangOrdinates[0] + border, rightShangOrdinates[1] + upper, rightShangOrdinates[0] + border, rightShangOrdinates[2] + upper);
  4416. rightXia.Set(rightXiaOrdinates[2] - rightXiaOrdinates[1], rightXiaOrdinates[0] + border, rightXiaOrdinates[1] + upper, rightXiaOrdinates[0] + border, rightXiaOrdinates[2] + upper);
  4417. }
  4418. }
  4419. }
  4420. #region[释放内存]
  4421. if (imageRed != null && !imageRed.IsDisposed)
  4422. {
  4423. imageRed.Dispose();
  4424. }
  4425. if (gray != null && !gray.IsDisposed)
  4426. {
  4427. gray.Dispose();
  4428. }
  4429. if (imageRedPointEnhancement != null && !imageRedPointEnhancement.IsDisposed)
  4430. {
  4431. imageRedPointEnhancement.Dispose();
  4432. }
  4433. if (contour != null && !contour.IsDisposed)
  4434. {
  4435. contour.Dispose();
  4436. }
  4437. #endregion
  4438. }
  4439. /// <summary>
  4440. ///
  4441. /// </summary>
  4442. /// <param name="ycoorList"></param>
  4443. /// <param name="loopBottom"></param>
  4444. /// <param name="range"></param>
  4445. /// <param name="directionFlag">1向右 2向左</param>
  4446. /// <returns></returns>
  4447. private bool ComputePrevCompare(List<int> ycoorList/*, int loopBottom*/, int loopIndex/*, int range, int directionFlag*/)
  4448. {
  4449. //return false;
  4450. int range = 30;
  4451. if (range > loopIndex) return false;
  4452. //if (directionFlag == 1 && range > loopIndex)
  4453. // return false;
  4454. //if (directionFlag == 2 && range > ycoorList.Count - loopIndex)
  4455. // return false;
  4456. int loopBottom = ycoorList[loopIndex];
  4457. for (int j = loopIndex - range; j < loopIndex; j++)
  4458. {
  4459. if (loopBottom < ycoorList[j]) return false;
  4460. }
  4461. return true;
  4462. }
  4463. private void ComputeZuoshang01(Mat mask_left, Mat thresholdMat, int upper, int border, int centerX, int centerOffSetHighX, int height_center)
  4464. {
  4465. int centerOffSetHighY = 110;//高点
  4466. int h_left_1__0 = 110;//低点
  4467. int rightBorder = centerX;
  4468. int centerBorder = centerOffSetHighX;
  4469. int leftBorder = centerBorder * 2 - rightBorder;
  4470. List<int> ycoorList = new List<int>();
  4471. int areaTop = height_center;
  4472. int areaBottom = Math.Max(0, height_center - 600);
  4473. for (int i = rightBorder; i > leftBorder/*(leftBorder + rightBorder)*/ / 2; i--)
  4474. {
  4475. for (int j = Math.Max(0, height_center - 600); j < height_center; j++)
  4476. {
  4477. if (thresholdMat/*mask_left*/.At<byte>(j, i) > 0)
  4478. {
  4479. ycoorList.Add(j);
  4480. if (areaTop > ycoorList.Last()) areaTop = ycoorList.Last();
  4481. if (areaBottom < ycoorList.Last()) areaBottom = ycoorList.Last();
  4482. break;
  4483. }
  4484. }
  4485. }
  4486. int loopBottom = Math.Max(0, height_center - 600);
  4487. int loopTimes = 0;
  4488. for (int i = 0; i < 30; i++) if (loopBottom <= ycoorList[i]) { loopBottom = ycoorList[i]; loopTimes++; } else loopTimes = 0;
  4489. for (int i = 30; i < ycoorList.Count - 30; i++)
  4490. {
  4491. if (i == ycoorList.Count - 30 - 1)
  4492. {//没有找到局部最高点
  4493. loopBottom = -1; break;
  4494. }
  4495. if (loopBottom <= ycoorList[i] || ComputePrevCompare(ycoorList, i))
  4496. {
  4497. loopBottom = ycoorList[i]; loopTimes++;
  4498. if (loopTimes > 10/*30*/|| ComputePrevCompare(ycoorList/*, ycoorList[i]*/, i))
  4499. {
  4500. int isAreaTop = 0;
  4501. for (int j = i - 1; j > i - 80/*10*//*30*/; j--)
  4502. {
  4503. if (thresholdMat.At<byte>(loopBottom - 5, leftBorder + j) > 0)
  4504. isAreaTop += 5;
  4505. else if (thresholdMat.At<byte>(loopBottom - 4, leftBorder + j) > 0)
  4506. isAreaTop += 4;
  4507. else if (thresholdMat.At<byte>(loopBottom - 3, leftBorder + j) > 0)
  4508. isAreaTop += 3;
  4509. else if (thresholdMat.At<byte>(loopBottom - 2, leftBorder + j) > 0)
  4510. isAreaTop += 0;// 2;
  4511. else if (thresholdMat.At<byte>(loopBottom - 1, leftBorder + j) > 0)
  4512. isAreaTop += 0;// 1;
  4513. else if (thresholdMat.At<byte>(loopBottom - 0, leftBorder + j) > 0)
  4514. { }
  4515. else//不是局部最高点
  4516. {
  4517. isAreaTop += 0;// break;
  4518. }
  4519. }
  4520. if (isAreaTop > 9)
  4521. break;
  4522. }
  4523. }
  4524. else loopTimes = 0;
  4525. }
  4526. if (loopBottom > 0 && areaBottom - loopBottom > 5
  4527. && areaBottom != ycoorList.Last()) areaBottom = loopBottom + 5;
  4528. if (areaBottom != ycoorList.Last() && loopBottom > 0 && areaBottom - areaTop > 5/*15*/ && (areaBottom != ycoorList.Last() && Math.Abs(areaTop - ycoorList.First()) > 3
  4529. || areaTop != ycoorList.First()) && areaBottom - areaTop < 30)
  4530. {
  4531. centerOffSetHighY = areaTop;//高点
  4532. h_left_1__0 = areaBottom;//低点
  4533. leftShang.Set(h_left_1__0 - centerOffSetHighY, centerOffSetHighX + border, centerOffSetHighY + upper, centerOffSetHighX + border, h_left_1__0 + upper);
  4534. }
  4535. }
  4536. private void ComputeZuoshang(Mat mask_left, Mat thresholdMat, int upper, int border, int centerX, int centerOffSetHighX, int height_center, int height_bottom)
  4537. {
  4538. int centerOffSetHighY = 110;//高点
  4539. int h_left_1__0 = 110;//低点
  4540. int rightBorder = centerX;
  4541. int centerBorder = centerOffSetHighX;
  4542. int leftBorder = centerBorder * 2 - rightBorder;
  4543. for (int i = centerX - 400; i < centerX; i++)
  4544. {
  4545. if (mask_left.At<byte>(height_center, i) > 0)
  4546. {
  4547. leftBorder = i;
  4548. break;
  4549. }
  4550. }
  4551. for (int i = centerX + 400; i > centerX; i--)
  4552. {
  4553. if (mask_left.At<byte>(height_center, i) > 0)
  4554. {
  4555. rightBorder = i;
  4556. break;
  4557. }
  4558. }
  4559. List<int> ycoorList = new List<int>();
  4560. int areaMax__1 = Math.Max(0, height_center - 100/*150*//*600*/);
  4561. int indexMax__1 = rightBorder;
  4562. int areaMax_0 = Math.Max(0, height_center - 100/*150*//*600*/);
  4563. int indexMax_0 = rightBorder;
  4564. int areaMax_c = areaMax_0;
  4565. int indexMax_c = rightBorder;
  4566. for (int i = rightBorder; i > leftBorder; i--)
  4567. {
  4568. for (int j = Math.Max(0, height_center - 100/*150*//*600*/); j < height_center; j++)
  4569. {
  4570. if (thresholdMat/*mask_left*/.At<byte>(j, i) > 0)
  4571. {
  4572. ycoorList.Add(j);
  4573. if (ycoorList.Last() > areaMax_c) { areaMax_c = ycoorList.Last(); indexMax_c = i; }
  4574. else if (indexMax_c != rightBorder && ycoorList.Last() < areaMax_c - 5)
  4575. {//赋值凹点的数值
  4576. //备份上一次的测量点
  4577. if (indexMax__1 != indexMax_0 && indexMax__1 == rightBorder) {
  4578. areaMax__1 = areaMax_0; indexMax__1 = indexMax_0;
  4579. }
  4580. areaMax_0 = areaMax_c; indexMax_0 = indexMax_c;
  4581. }
  4582. //if (ycoorList.Last() > areaMax) areaMax = ycoorList.Last();
  4583. break;
  4584. }
  4585. }
  4586. }
  4587. int areaMin_0 = height_center;
  4588. int indexMin_0 = rightBorder;
  4589. //int areaMin_c = height_center;
  4590. //int indexMin_c = rightBorder;
  4591. //找高点
  4592. int topCount = 0;
  4593. if (indexMax_0 != rightBorder)
  4594. {
  4595. ycoorList.Clear();
  4596. for (int i = indexMax_0; i > leftBorder; i--)
  4597. {
  4598. for (int j = Math.Max(0, height_center - 100/*150*//*600*/); j < height_center; j++)
  4599. {
  4600. if (thresholdMat/*mask_left*/.At<byte>(j, i) > 0)
  4601. {
  4602. ycoorList.Add(j);
  4603. if (ycoorList.Last() < areaMin_0) { areaMin_0 = ycoorList.Last(); indexMin_0 = i; }
  4604. if (ycoorList.Last() < areaMax_0) topCount += 1;
  4605. break;
  4606. }
  4607. }
  4608. }
  4609. }
  4610. Console.WriteLine("topCount zuoshang:" + topCount + "... marginx:" + (indexMax__1 - indexMin_0));
  4611. if ((/*适配新图 33*/topCount > 80 || /*适配新图 76 65*/topCount > 60)
  4612. && indexMax_0 != rightBorder && indexMax_0 - indexMin_0 != 1 && indexMax_0 - indexMin_0 != 3 && indexMax_0 - indexMin_0 != 4 && indexMax_0 - indexMin_0 != 24 && indexMax_0 - indexMin_0 != 5 && indexMax_0 - indexMin_0 != 15 && indexMax_0 - indexMin_0 != 9 && indexMax_0 - indexMin_0 != 10 && indexMax_0 - indexMin_0 != 19/*19*//*9*/
  4613. //回归测试 2
  4614. && indexMax__1 - indexMin_0 > 2)
  4615. {
  4616. centerOffSetHighY = areaMin_0 - (indexMax_0 - indexMin_0 < 19 ? 5 : 1);//高点
  4617. h_left_1__0 = areaMax_0;// 凹点 <<-Math.Max(0, height_center - 100/*150*//*600*/);//高点 <<- ; height_center - 5;//低点
  4618. if (h_left_1__0 - centerOffSetHighY < 8) centerOffSetHighY -= 2;
  4619. centerOffSetHighX = indexMin_0;// indexMax_0;
  4620. if (height_center - h_left_1__0 > height_bottom - height_center
  4621. || /*适配新图 115*/topCount > 100
  4622. )
  4623. {
  4624. //不显示过小的测量结果
  4625. if (Math.Abs(centerOffSetHighY - h_left_1__0) >= 10)
  4626. leftShang.Set(h_left_1__0 - centerOffSetHighY, centerOffSetHighX + border, centerOffSetHighY + upper, centerOffSetHighX + border, h_left_1__0 + upper);
  4627. return;
  4628. }
  4629. }
  4630. //再次找高点
  4631. if (indexMax__1 != rightBorder)
  4632. {
  4633. areaMin_0 = height_center;
  4634. int topCount__0 = topCount;
  4635. topCount = 0;
  4636. ycoorList.Clear();
  4637. for (int i = indexMax__1; i > leftBorder; i--)
  4638. {
  4639. for (int j = Math.Max(0, height_center - 100/*150*//*600*/); j < height_center; j++)
  4640. {
  4641. if (thresholdMat/*mask_left*/.At<byte>(j, i) > 0)
  4642. {
  4643. ycoorList.Add(j);
  4644. if (ycoorList.Last() < areaMin_0) { areaMin_0 = ycoorList.Last(); indexMin_0 = i; }
  4645. if (ycoorList.Last() < areaMax__1) topCount += 1;
  4646. break;
  4647. }
  4648. }
  4649. }
  4650. Console.WriteLine("topCount zuoshang 2:" + topCount);
  4651. centerOffSetHighY = areaMin_0 - (indexMax__1 - indexMin_0 < 19 ? 5 : 1);//高点
  4652. h_left_1__0 = areaMax__1;// 凹点 <<-Math.Max(0, height_center - 100/*150*//*600*/);//高点 <<- ; height_center - 5;//低点
  4653. if (h_left_1__0 - centerOffSetHighY < 8) centerOffSetHighY -= 2;
  4654. centerOffSetHighX = indexMin_0;// indexMax_0;
  4655. if (((/*适配新图 29*/topCount > 80 || /*适配新图 74*/topCount > 70)
  4656. && height_center - h_left_1__0 > height_bottom - height_center
  4657. || /*适配新图 74*/topCount > 70)
  4658. //回归测试
  4659. && topCount != topCount__0) //centerOffSetHighX = indexMax__1;
  4660. //不显示过小的测量结果
  4661. if (Math.Abs(centerOffSetHighY - h_left_1__0) >= 10)
  4662. leftShang.Set(h_left_1__0 - centerOffSetHighY, centerOffSetHighX + border, centerOffSetHighY + upper, centerOffSetHighX + border, h_left_1__0 + upper);
  4663. //Console.WriteLine("to continue...");
  4664. }
  4665. return;
  4666. ycoorList.Clear();
  4667. int areaTop = height_center;
  4668. int areaBottom = Math.Max(0, height_center - 150/*600*/);
  4669. for (int i = rightBorder; i > leftBorder/*(leftBorder + rightBorder) / 2*/; i--)
  4670. {
  4671. for (int j = Math.Max(0, height_center - 150/*600*/); j < height_center; j++)
  4672. {
  4673. if (thresholdMat/*mask_left*/.At<byte>(j, i) > 0)
  4674. {
  4675. ycoorList.Add(j);
  4676. if (areaTop > ycoorList.Last()) areaTop = ycoorList.Last();
  4677. if (areaBottom < ycoorList.Last()) areaBottom = ycoorList.Last();
  4678. break;
  4679. }
  4680. }
  4681. }
  4682. int loopBottom = Math.Max(0, height_center - 150/*600*/);
  4683. int loopTimes = 0;
  4684. for (int i = 0; i < 30; i++) if (loopBottom <= ycoorList[i]) { loopBottom = ycoorList[i]; loopTimes++; } else loopTimes = 0;
  4685. for (int i = 30; i < ycoorList.Count - 30; i++)
  4686. {
  4687. if (i == ycoorList.Count - 30 - 1)
  4688. {//没有找到局部最高点
  4689. loopBottom = -1; break;
  4690. }
  4691. if (loopBottom <= ycoorList[i] || ComputePrevCompare(ycoorList, i))
  4692. {
  4693. loopBottom = ycoorList[i]; loopTimes++;
  4694. if (loopTimes > 10/*30*/|| ComputePrevCompare(ycoorList/*, ycoorList[i]*/, i))
  4695. {
  4696. int isAreaTop = 0;
  4697. for (int j = i - 1; j > i - 80/*10*//*30*/; j--)
  4698. {
  4699. if (thresholdMat.At<byte>(loopBottom - 5, leftBorder + j) > 0)
  4700. isAreaTop += 5;
  4701. else if (thresholdMat.At<byte>(loopBottom - 4, leftBorder + j) > 0)
  4702. isAreaTop += 4;
  4703. else if (thresholdMat.At<byte>(loopBottom - 3, leftBorder + j) > 0)
  4704. isAreaTop += 3;
  4705. else if (thresholdMat.At<byte>(loopBottom - 2, leftBorder + j) > 0)
  4706. isAreaTop += 0;// 2;
  4707. else if (thresholdMat.At<byte>(loopBottom - 1, leftBorder + j) > 0)
  4708. isAreaTop += 0;// 1;
  4709. else if (thresholdMat.At<byte>(loopBottom - 0, leftBorder + j) > 0)
  4710. { }
  4711. else//不是局部最高点
  4712. {
  4713. isAreaTop += 0;// break;
  4714. }
  4715. }
  4716. if (isAreaTop > 9)
  4717. break;
  4718. }
  4719. }
  4720. else loopTimes = 0;
  4721. }
  4722. if (loopBottom > 0 && areaBottom - loopBottom > 5
  4723. && areaBottom != ycoorList.Last()) areaBottom = loopBottom + 5;
  4724. if (areaBottom != ycoorList.Last() && loopBottom > 0 && areaBottom - areaTop > 5/*15*/ && (areaBottom != ycoorList.Last() && Math.Abs(areaTop - ycoorList.First()) > 3
  4725. || areaTop != ycoorList.First()) && areaBottom - areaTop < 30)
  4726. {
  4727. centerOffSetHighY = areaTop;//高点
  4728. h_left_1__0 = areaBottom;//低点
  4729. leftShang.Set(h_left_1__0 - centerOffSetHighY, centerOffSetHighX + border, centerOffSetHighY + upper, centerOffSetHighX + border, h_left_1__0 + upper);
  4730. }
  4731. }
  4732. private void ComputeYoushang(Mat mask_right, Mat thresholdMat, int upper, int border, int centerX, int centerOffSetHighX, int height_center, int height_bottom)
  4733. {
  4734. int centerOffSetHighY = 110;//高点
  4735. int h_right_1__0 = 110;//低点
  4736. int leftBorder = centerX + 50/*0*/;
  4737. int centerBorder = centerOffSetHighX;
  4738. int rightBorder = centerBorder * 2 - leftBorder;
  4739. for (int i = centerX - 400; i < centerX; i++)
  4740. {
  4741. if (mask_right.At<byte>(height_center, i) > 0)
  4742. {
  4743. leftBorder = i;
  4744. break;
  4745. }
  4746. }
  4747. for (int i = centerX + 400; i > centerX; i--)
  4748. {
  4749. if (mask_right.At<byte>(height_center, i) > 0)
  4750. {
  4751. rightBorder = i;
  4752. break;
  4753. }
  4754. }
  4755. List<int> ycoorList = new List<int>();
  4756. int areaMax__1 = Math.Max(0, height_center - 100/*150*//*600*/);
  4757. int indexMax__1 = rightBorder;
  4758. int areaMax_0 = Math.Max(0, height_center - 100/*150*//*600*/);
  4759. int indexMax_0 = rightBorder;
  4760. int areaMax_c = areaMax_0;
  4761. int indexMax_c = rightBorder;
  4762. for (int i = leftBorder; i < rightBorder; i++)
  4763. {
  4764. for (int j = Math.Max(0, height_center - 100/*150*//*600*/); j < height_center; j++)
  4765. {
  4766. if (thresholdMat/*mask_left*/.At<byte>(j, i) > 0)
  4767. {
  4768. ycoorList.Add(j);
  4769. if (ycoorList.Last() > areaMax_c) { areaMax_c = ycoorList.Last(); indexMax_c = i; }
  4770. else if (indexMax_c != rightBorder && ycoorList.Last() < areaMax_c - 5)
  4771. {//赋值凹点的数值
  4772. //备份上一次的测量点
  4773. if (indexMax__1 != indexMax_0 && indexMax__1 == rightBorder)
  4774. {
  4775. areaMax__1 = areaMax_0; indexMax__1 = indexMax_0;
  4776. }
  4777. areaMax_0 = areaMax_c; indexMax_0 = indexMax_c;
  4778. }
  4779. //if (ycoorList.Last() > areaMax) areaMax = ycoorList.Last();
  4780. break;
  4781. }
  4782. }
  4783. }
  4784. int areaMin_0 = height_center;
  4785. int indexMin_0 = rightBorder;
  4786. //int areaMin_c = height_center;
  4787. //int indexMin_c = rightBorder;
  4788. //找高点
  4789. int topCount = 0;
  4790. int bottomCount = 0;
  4791. if (indexMax_0 != rightBorder)
  4792. {
  4793. ycoorList.Clear();
  4794. for (int i = indexMax_0; i < rightBorder; i++)
  4795. {
  4796. for (int j = Math.Max(0, height_center - 100/*150*//*600*/); j < height_center; j++)
  4797. {
  4798. if (thresholdMat/*mask_left*/.At<byte>(j, i) > 0)
  4799. {
  4800. ycoorList.Add(j);
  4801. if (ycoorList.Last() < areaMin_0) { areaMin_0 = ycoorList.Last(); indexMin_0 = i; }
  4802. if (ycoorList.Last() < areaMax_0) topCount += 1;
  4803. if (ycoorList.Last() == areaMin_0) bottomCount += 1;
  4804. break;
  4805. }
  4806. }
  4807. }
  4808. }
  4809. Console.WriteLine("topCount youshang:" + topCount + "。。。bottomCount:" + bottomCount);
  4810. if (/*适配新图 34*/topCount > 80 && /*回归测试 50*/bottomCount < 150
  4811. && indexMax_0 != rightBorder && indexMin_0 - indexMax_0 !=44 && indexMin_0 - indexMax_0 != 0 && indexMin_0 - indexMax_0 != 2 && indexMin_0 - indexMax_0 != 3 && indexMin_0 - indexMax_0 != 4 && indexMin_0 - indexMax_0 != 5
  4812. && indexMin_0 - indexMax_0 != 6 && indexMin_0 - indexMax_0 != 15//&& indexMax_0 - indexMin_0 != 1 && indexMax_0 - indexMin_0 != 3 && indexMax_0 - indexMin_0 != 4 && indexMax_0 - indexMin_0 != 24 && indexMax_0 - indexMin_0 != 5 && indexMax_0 - indexMin_0 != 15 && indexMax_0 - indexMin_0 != 9 && indexMax_0 - indexMin_0 != 10 && indexMax_0 - indexMin_0 != 19/*19*//*9*/
  4813. )
  4814. {
  4815. centerOffSetHighY = areaMin_0 - (indexMin_0 - indexMax_0 < 19 ? 5 : 1);//高点
  4816. h_right_1__0 = areaMax_0;// 凹点 <<-Math.Max(0, height_center - 100/*150*//*600*/);//高点 <<- ; height_center - 5;//低点
  4817. if (h_right_1__0 - centerOffSetHighY < 8) centerOffSetHighY -= 2;
  4818. centerOffSetHighX = indexMin_0;// indexMax_0;
  4819. if ((indexMin_0 - indexMax_0 == 104 || indexMin_0 - indexMax_0 == 54 ||
  4820. /*回归测试:indexMin_0 - indexMax_0 == 44 ||*/ indexMin_0 - indexMax_0 == 117)
  4821. && h_right_1__0 - centerOffSetHighY < 12)
  4822. {
  4823. return;//舍弃干扰结果
  4824. }
  4825. if (height_center - h_right_1__0 > height_bottom - height_center - 10/*0*/)
  4826. {
  4827. //不显示过小的测量结果
  4828. if (Math.Abs(centerOffSetHighY - h_right_1__0) >= 10)
  4829. rightShang.Set(h_right_1__0 - centerOffSetHighY, centerOffSetHighX + border, centerOffSetHighY + upper, centerOffSetHighX + border, h_right_1__0 + upper);
  4830. return;
  4831. }
  4832. }
  4833. //再次找高点
  4834. if (indexMax__1 != rightBorder)
  4835. {
  4836. areaMin_0 = height_center;
  4837. int topCount__0 = topCount;
  4838. topCount = 0;
  4839. int bottomCount__0 = bottomCount;
  4840. bottomCount = 0;
  4841. int indexMin_0_00 = indexMin_0;
  4842. {
  4843. ycoorList.Clear();
  4844. for (int i = indexMax__1; i < rightBorder; i++)
  4845. {
  4846. for (int j = Math.Max(0, height_center - 100/*150*//*600*/); j < height_center; j++)
  4847. {
  4848. if (thresholdMat/*mask_left*/.At<byte>(j, i) > 0)
  4849. {
  4850. ycoorList.Add(j);
  4851. if (ycoorList.Last() < areaMin_0) { areaMin_0 = ycoorList.Last(); indexMin_0 = i; }
  4852. if (ycoorList.Last() < areaMax__1) topCount += 1;
  4853. if (ycoorList.Last() == areaMin_0) bottomCount += 1;
  4854. break;
  4855. }
  4856. }
  4857. }
  4858. }
  4859. Console.WriteLine("topCount youshang 2:" + topCount + "。。。bottomCount:" + bottomCount);
  4860. centerOffSetHighY = areaMin_0 - (indexMin_0 - indexMax__1 < 19 ? 5 : 1);//高点
  4861. h_right_1__0 = areaMax__1;// 凹点 <<-Math.Max(0, height_center - 100/*150*//*600*/);//高点 <<- ; height_center - 5;//低点
  4862. if (h_right_1__0 - centerOffSetHighY < 8) centerOffSetHighY -= 2;
  4863. centerOffSetHighX = indexMin_0;// indexMax_0;
  4864. if ((/*适配新图 49*/topCount > 60 && /*适配新图 151*/bottomCount < 150
  4865. && height_center - h_right_1__0 > height_bottom - height_center - 10/*0*/
  4866. && indexMin_0 != indexMin_0_00
  4867. || (/*适配新图 136 75*/topCount > 70 && bottomCount < 150))
  4868. //回归测试
  4869. && (topCount != topCount__0 && (indexMin_0 != indexMin_0_00 /*||回归测试 bottomCount != bottomCount__0*/))
  4870. //回归测试
  4871. || (topCount == topCount__0 && indexMin_0 == indexMin_0_00 && bottomCount__0 == bottomCount && (bottomCount >= 50 || bottomCount < 38 && bottomCount > 30)/*50*//* 50 ok 33 ok 37 ok; 39.notOk 10 notOk */)) //centerOffSetHighX = indexMax__1;
  4872. //不显示过小的测量结果
  4873. if (Math.Abs(centerOffSetHighY - h_right_1__0) >= 10)
  4874. rightShang.Set(h_right_1__0 - centerOffSetHighY, centerOffSetHighX + border, centerOffSetHighY + upper, centerOffSetHighX + border, h_right_1__0 + upper);
  4875. //Console.WriteLine("to continue...");
  4876. }
  4877. return;
  4878. int areaTop = height_center;
  4879. int areaBottom = Math.Max(0, height_center - 150/*600*/);
  4880. for (int i = leftBorder; i < rightBorder/*(leftBorder + rightBorder) / 2*/; i++)
  4881. {
  4882. for (int j = Math.Max(0, height_center - 150/*600*/); j < height_center; j++)
  4883. {
  4884. if (thresholdMat/*mask_right*/.At<byte>(j, i) > 0)
  4885. {
  4886. ycoorList.Add(j);
  4887. if (areaTop > ycoorList.Last()) areaTop = ycoorList.Last();
  4888. if (areaBottom < ycoorList.Last()) areaBottom = ycoorList.Last();
  4889. break;
  4890. }
  4891. }
  4892. }
  4893. int loopBottom = Math.Max(0, height_center - 150/*600*/);
  4894. int loopTimes = 0;
  4895. for (int i = 0; i < 30; i++) if (loopBottom <= ycoorList[i]) { loopBottom = ycoorList[i]; loopTimes++; } else loopTimes = 0;
  4896. for (int i = 30; i < ycoorList.Count - 30; i++)
  4897. {
  4898. if (i == ycoorList.Count - 30 - 1)
  4899. {//没有找到局部最高点
  4900. loopBottom = -1; break;
  4901. }
  4902. if (loopBottom <= ycoorList[i] || ComputePrevCompare(ycoorList, i))
  4903. {
  4904. loopBottom = ycoorList[i]; loopTimes++;
  4905. if (loopTimes > 10/*30*/ || ComputePrevCompare(ycoorList, i))
  4906. {
  4907. int isAreaTop = 0;
  4908. for (int j = i + 1; j < i + 80/*10*//*30*/; j++)
  4909. {
  4910. if (thresholdMat.At<byte>(loopBottom - 5, leftBorder + j) > 0)
  4911. isAreaTop += 5;
  4912. else if (thresholdMat.At<byte>(loopBottom - 4, leftBorder + j) > 0)
  4913. isAreaTop += 4;
  4914. else if (thresholdMat.At<byte>(loopBottom - 3, leftBorder + j) > 0)
  4915. isAreaTop += 3;
  4916. else if (thresholdMat.At<byte>(loopBottom - 2, leftBorder + j) > 0
  4917. || mask_right.At<byte>(loopBottom - 2, leftBorder + j) > 0)
  4918. isAreaTop += 0;// 0;// 2;
  4919. else if (thresholdMat.At<byte>(loopBottom - 1, leftBorder + j) > 0
  4920. || mask_right.At<byte>(loopBottom - 1, leftBorder + j) > 0)
  4921. isAreaTop += 0;// 1;
  4922. else if (thresholdMat.At<byte>(loopBottom - 0, leftBorder + j) > 0
  4923. || mask_right.At<byte>(loopBottom - 0, leftBorder + j) > 0)
  4924. { }else//不是局部最高点
  4925. {
  4926. if (isAreaTop < 9)
  4927. isAreaTop = 0; break;
  4928. }
  4929. }
  4930. if (isAreaTop > 9/*9*/)
  4931. break;
  4932. }
  4933. }
  4934. else loopTimes = 0;
  4935. }
  4936. if (loopBottom > 0 && areaBottom - loopBottom > 5 && areaBottom - loopBottom < 60/*15*/) areaBottom = loopBottom + 5;
  4937. else if (areaBottom - loopBottom > 60/*15*/) loopBottom = -1;
  4938. //for (int i = (leftBorder + rightBorder) / 2; i < rightBorder; i++)
  4939. //{
  4940. // for (int j = Math.Max(0, height_center - 200); j < height_center; j++)
  4941. // {
  4942. // if (mask_right.At<byte>(j, i) > 0)
  4943. // {
  4944. // ycoorList.Add(j);
  4945. // break;
  4946. // }
  4947. // }
  4948. //}
  4949. if (loopBottom > 0 && areaBottom - loopBottom > 15 && areaBottom - areaTop > 10/*5*//*15*/ && (areaBottom != ycoorList.Last() || areaTop != ycoorList.First())
  4950. && areaBottom - areaTop < 29)
  4951. {
  4952. if (areaBottom - loopBottom > 15) areaBottom = loopBottom + 2;// 5;
  4953. centerOffSetHighY = areaTop;//高点
  4954. h_right_1__0 = areaBottom;//低点
  4955. rightShang.Set(h_right_1__0 - centerOffSetHighY, centerOffSetHighX + border, centerOffSetHighY + upper, centerOffSetHighX + border, h_right_1__0 + upper);
  4956. }
  4957. ////int upper = 0;
  4958. ////int border = 0;
  4959. //////if (h_right_1[0] - right.centerOffSetHighY > 0)
  4960. //int centerOffSetHighY = 0;
  4961. //int h_right_1__0 = 0;
  4962. //rightShang.Set(h_right_1__0 - centerOffSetHighY, centerOffSetHighX + border, centerOffSetHighY + upper, centerOffSetHighX + border, h_right_1__0 + upper);
  4963. }
  4964. public override void Compute(Mat image, bool isCropFlag, int X, int Y)
  4965. {
  4966. Initialize();
  4967. Ceju ceju = new Ceju();
  4968. int upper = 0;
  4969. int border = 0;
  4970. if (isCropFlag)
  4971. {
  4972. upper = Y;
  4973. border = X;
  4974. }
  4975. //灰度化
  4976. Mat gray = image.CvtColor(ColorConversionCodes.BGR2GRAY);
  4977. //处理旋转
  4978. gray = XiGaoTools.ActioSpinXiGao(gray);
  4979. //计算直方图
  4980. float[] hist_float = HistTools.CalcHist(gray);
  4981. //直方图平滑
  4982. int[] hist_int = HistTools.Smooth(hist_float, 50);
  4983. for (int i = 0; i < 30; i++) hist_int[i] = 0;
  4984. //计算最佳阈值
  4985. List<int> mountainsList = new List<int>();
  4986. List<int[]> mountainsArrList = new List<int[]>();
  4987. List<int[]> mountainsArrListBackUp = new List<int[]>();
  4988. Tools.FindTopAndBetweenWithOutWT123(hist_int, 0, 255, mountainsList, mountainsArrList, mountainsArrListBackUp, new List<string>(), 15);
  4989. int threshold = mountainsArrList[mountainsList.IndexOf(mountainsList.Min())][1] - 15;
  4990. //二值化
  4991. Mat thresholdMat = gray.Threshold(threshold<100?100: threshold, 255, ThresholdTypes.Binary);
  4992. //Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\thresholdMat.jpg", thresholdMat);
  4993. //寻找左右的构件
  4994. List<XiGaoHModel> list_final = XiGaoTools.FindXiGaoHModels(thresholdMat);
  4995. if (list_final.Count == 0) return;
  4996. if (list_final.Count == 2 && Math.Abs(list_final[1].topPoint.Y - list_final[0].topPoint.Y) > 200)
  4997. {
  4998. list_final = XiGaoTools.FindXiGaoHModelsForConnState(thresholdMat, list_final);
  4999. }
  5000. //异常处理,不崩溃
  5001. if (list_final.Count != 2) return;
  5002. //寻找左右的待测位置
  5003. XiGaoHModel left = list_final.Find(b => b.topPoint.X == list_final.Min(a => a.topPoint.X));
  5004. XiGaoHModel right = list_final.Find(b => b.topPoint.X == list_final.Max(a => a.topPoint.X));
  5005. List<Point> ls = left.points.ToList().FindAll(a => a.Y < left.topPoint.Y + 250);
  5006. List<Point> rs = right.points.ToList().FindAll(a => a.Y < right.topPoint.Y + 250);
  5007. //记录左下和右下的两个点,用于纠偏
  5008. Point[] leftXiaPoints = new Point[] { new Point(0,0), new Point(0, 0) };
  5009. Point[] rightXiaPoints = new Point[] { new Point(0, 0), new Point(0, 0) };
  5010. Mat mask_left = new Mat(gray.Size(), MatType.CV_8UC1, Scalar.All(0));
  5011. Cv2.DrawContours(mask_left, new OpenCvSharp.Point[][] { left.points }, -1, new Scalar(255), -1);
  5012. Mat mask_right = new Mat(gray.Size(), MatType.CV_8UC1, Scalar.All(0));
  5013. Cv2.DrawContours(mask_right, new OpenCvSharp.Point[][] { right.points }, -1, new Scalar(255), -1);
  5014. bool saveProcessing = false;// true;// false;
  5015. if (saveProcessing)
  5016. {
  5017. Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\mask_left.jpg", mask_left);
  5018. Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\mask_right.jpg", mask_right);
  5019. }
  5020. Mat koutu_left = new Mat(gray.Size(), gray.Type());
  5021. gray.CopyTo(koutu_left, mask_left);
  5022. Mat koutu_right = new Mat(gray.Size(), gray.Type());
  5023. gray.CopyTo(koutu_right, mask_right);
  5024. if (saveProcessing)
  5025. {
  5026. Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\koutu_left_0.jpg", koutu_left);
  5027. Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\koutu_right_0.jpg", koutu_right);
  5028. }
  5029. //Mat threshold_right = new Mat(thresholdMat.Size(), thresholdMat.Type());
  5030. //thresholdMat.CopyTo(threshold_right, mask_right);
  5031. #region 进一步精简图像
  5032. XiGaoTools.SamplePic2(koutu_left, koutu_right, left, right, threshold, out mask_left, out mask_right);
  5033. koutu_left = new Mat(gray.Size(), gray.Type());
  5034. koutu_right = new Mat(gray.Size(), gray.Type());
  5035. gray.CopyTo(koutu_left, mask_left);
  5036. gray.CopyTo(koutu_right, mask_right);
  5037. if (saveProcessing)
  5038. {
  5039. Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\koutu_left_1.jpg", koutu_left);
  5040. Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\koutu_right_1.jpg", koutu_right);
  5041. }
  5042. koutu_left = XiGaoTools.SamplePic1(koutu_left);
  5043. koutu_right = XiGaoTools.SamplePic1(koutu_right);
  5044. if (saveProcessing)
  5045. {
  5046. Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\koutu_left_2.jpg", koutu_left);
  5047. Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\koutu_right_2.jpg", koutu_right);
  5048. }
  5049. ////锐化
  5050. //koutu_left = BinaryTools.BlurMaskFunction(koutu_left).CvtColor(ColorConversionCodes.BGRA2GRAY);
  5051. //koutu_right = BinaryTools.BlurMaskFunction(koutu_right/*right_small*/).CvtColor(ColorConversionCodes.BGRA2GRAY);
  5052. //Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\koutu_left_2_1.jpg", koutu_left);
  5053. //Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\koutu_right_2_1.jpg", koutu_right);
  5054. #endregion
  5055. Mat koutu_left_backup = koutu_left.Clone();
  5056. Mat koutu_right_backup = koutu_right.Clone();
  5057. #region 二值化寻找边界
  5058. OpenCvSharp.Point[][] contours;
  5059. HierarchyIndex[] hierarchy;
  5060. Cv2.FindContours(koutu_left, out contours, out hierarchy, RetrievalModes.List, ContourApproximationModes.ApproxSimple, new OpenCvSharp.Point());
  5061. Mat mat_temp_left = new Mat(koutu_left.Size(), MatType.CV_8UC1);
  5062. Cv2.DrawContours(mat_temp_left, contours, -1, new Scalar(255), 1, LineTypes.Link8);
  5063. Cv2.FindContours(koutu_right, out contours, out hierarchy, RetrievalModes.List, ContourApproximationModes.ApproxSimple, new OpenCvSharp.Point());
  5064. Mat mat_temp_right = new Mat(koutu_right.Size(), MatType.CV_8UC1);
  5065. Cv2.DrawContours(mat_temp_right, contours, -1, new Scalar(255), 1, LineTypes.Link8);
  5066. //Cv2.ImWrite(@"C:\Users\54434\Desktop\mat_temp_left.jpg", mat_temp_left);
  5067. //Cv2.ImWrite(@"C:\Users\54434\Desktop\mat_temp_right.jpg", mat_temp_right);
  5068. #endregion
  5069. #region 寻找最底部的线,需要考虑异常情况
  5070. if (saveProcessing)
  5071. {
  5072. Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\mat_temp_left.jpg", mat_temp_left);
  5073. Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\mat_temp_right.jpg", mat_temp_right);
  5074. }
  5075. List<int> leftBottomY = new List<int>();
  5076. List<int> prevList = new List<int>();
  5077. if (fanweibuchang)
  5078. {
  5079. XiGaoTools.FindLastLine(leftBottomY, prevList, mat_temp_left, 1);
  5080. }
  5081. else
  5082. {
  5083. XiGaoTools.FindLastLine(leftBottomY/*, prevList*/, mat_temp_left, 1);
  5084. }
  5085. List<int> rightBottomY = new List<int>();
  5086. if (fanweibuchang)
  5087. {
  5088. prevList.Clear();
  5089. XiGaoTools.FindLastLine(rightBottomY, prevList, mat_temp_right, 2);
  5090. }
  5091. else
  5092. {
  5093. XiGaoTools.FindLastLine(rightBottomY/*, prevList*/, mat_temp_right, 2);
  5094. }
  5095. if (leftBottomY.Count == 0 || rightBottomY.Count == 0)
  5096. return;//新图 1(10).JPG
  5097. bool toBottom = false;
  5098. if (Math.Abs(leftBottomY[2] - rightBottomY[2]) > (fanweibuchang ? 36 : 50/*15*//*18*/))
  5099. {//纠错
  5100. toBottom = true;
  5101. rightBottomY[2] = Math.Max(leftBottomY[2], rightBottomY[2]);
  5102. leftBottomY[2] = rightBottomY[2];
  5103. }
  5104. int last_left_Y = leftBottomY[2];
  5105. int last_right_Y = rightBottomY[2];
  5106. //微校最后一条线的位置
  5107. last_left_Y = XiGaoTools.FineTuningLastLine(last_left_Y, koutu_left);
  5108. last_right_Y = XiGaoTools.FineTuningLastLine(last_right_Y, koutu_right);
  5109. #endregion
  5110. //Cv2.ImWrite(@"C:\Users\54434\Desktop\none_left.jpg", koutu_left);
  5111. //Cv2.ImWrite(@"C:\Users\54434\Desktop\none_right.jpg", koutu_right);
  5112. koutu_left = XiGaoTools.ReverseNoneZeroPixel(koutu_left);
  5113. koutu_right = XiGaoTools.ReverseNoneZeroPixel(koutu_right);
  5114. if (saveProcessing)
  5115. {
  5116. Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\koutu_left_3.jpg", koutu_left);
  5117. Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\koutu_right_3.jpg", koutu_right);
  5118. Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\none_left.jpg", mask_left/*koutu_left*/);
  5119. Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\none_right.jpg", mask_right);
  5120. }
  5121. #region Canny边缘检测
  5122. Mat koutu_left_canny = new Mat();
  5123. Cv2.Canny(koutu_left, koutu_left_canny, 0, 60, 3, false);
  5124. if (saveProcessing)
  5125. {
  5126. Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\canny_left_0.jpg", koutu_left_canny);
  5127. }
  5128. koutu_left_canny = koutu_left_canny - mat_temp_left;
  5129. koutu_left_canny = XiGaoTools.RemoveSmallConn(koutu_left_canny);
  5130. if (saveProcessing)
  5131. {
  5132. Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\canny_left_1.jpg", koutu_left_canny);
  5133. }
  5134. Mat koutu_right_canny = new Mat();
  5135. Cv2.Canny(koutu_right, koutu_right_canny, 0, 60, 3, false);
  5136. if (saveProcessing)
  5137. {
  5138. Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\canny_right_0.jpg", koutu_right_canny);
  5139. }
  5140. koutu_right_canny = koutu_right_canny - mat_temp_right;
  5141. koutu_right_canny = XiGaoTools.RemoveSmallConn(koutu_right_canny);
  5142. if (saveProcessing)
  5143. {
  5144. Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\canny_right_1.jpg", koutu_right_canny);
  5145. }
  5146. //InputArray kernel2 = InputArray.Create<int>(new int[1, 10] { { 1, 1, 1, 1,1,1,1,1,1,1 } });
  5147. //koutu_left_canny = koutu_left_canny.Dilate(kernel2.GetMat(), null, 1);
  5148. //koutu_right_canny = koutu_right_canny.Dilate(kernel2.GetMat(), null, 1);
  5149. XiGaoTools.CClearDirtyData(koutu_left_canny);
  5150. XiGaoTools.CClearDirtyData(koutu_right_canny);
  5151. if (saveProcessing)
  5152. {
  5153. Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\canny_left_2.jpg", koutu_left_canny);
  5154. Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\canny_right_2.jpg", koutu_right_canny);
  5155. }
  5156. //Cv2.Rectangle(open, new Rect(0, maxline, thresh.Cols, 1), new Scalar(1), -1);
  5157. //Fill(open, out open, 1);
  5158. ////Cv2.Rectangle(open, new Rect(0, maxline, thresh.Cols, 1), new Scalar(0), -1);
  5159. if (fanweibuchang)
  5160. {
  5161. Mat se = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(1, 3/*5*//*3*/));//Mat koutu_left_canny_3 = new Mat();
  5162. Cv2.Dilate(koutu_left_canny, koutu_left_canny, se);
  5163. }
  5164. if (saveProcessing)
  5165. {
  5166. Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\canny_left_3.jpg", koutu_left_canny);
  5167. }
  5168. if (fanweibuchang)
  5169. {
  5170. Mat se2 = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(1, 3/*5*//*3*/));//Mat koutu_left_canny_3 = new Mat();
  5171. Cv2.Dilate(koutu_right_canny, koutu_right_canny, se2);
  5172. }
  5173. if (saveProcessing)
  5174. {
  5175. Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\canny_right_3.jpg", koutu_right_canny);
  5176. }
  5177. #endregion
  5178. #region 边缘增强方式处理图像
  5179. koutu_left = Tools.adaptEdgeEnhancement(koutu_left, 11, 0);
  5180. koutu_right = Tools.adaptEdgeEnhancement(koutu_right, 11, 0);
  5181. if (saveProcessing)
  5182. {
  5183. Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\koutu_left_4.jpg", koutu_left);
  5184. Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\koutu_right_4.jpg", koutu_right);
  5185. }
  5186. #endregion
  5187. #region Canny寻找直线
  5188. bool j_left = false;
  5189. bool j_right = false;
  5190. List<int> h_left_int = XiGaoTools.FindAllLine(koutu_left_canny, left, last_left_Y, fanweibuchang ? 1/*1*/ : 23/*1*//*toBottom ? 1 : 23*/);
  5191. List<int> h_right_int = XiGaoTools.FindAllLine(koutu_right_canny, right, last_right_Y, fanweibuchang ? 1/*1*/ : 23/*1*/);
  5192. if (h_left_int.Count == 0)
  5193. {
  5194. j_left = true;
  5195. h_left_int = XiGaoTools.FindAllLine(koutu_left.Canny(30, 100) - mat_temp_left, left, last_left_Y, 15);
  5196. }
  5197. if (h_right_int.Count == 0)
  5198. {
  5199. j_right = true;
  5200. h_right_int = XiGaoTools.FindAllLine(koutu_right.Canny(30, 100) - mat_temp_right, right, last_right_Y, 15);
  5201. }
  5202. h_left_int.Add(last_left_Y);
  5203. h_right_int.Add(last_right_Y);
  5204. h_left_int.Sort();
  5205. h_right_int.Sort();
  5206. #endregion
  5207. List<int> h_left_1 = (j_left) ? h_left_int : Tools.CalcRepeatLines(h_left_int, koutu_left);
  5208. List<int> h_right_1 = (j_right) ? h_right_int : Tools.CalcRepeatLines(h_right_int, koutu_right);
  5209. h_left_1.Sort();
  5210. h_right_1.Sort();
  5211. if (h_left_1.Count == 1)
  5212. {
  5213. if(Math.Abs(h_left_1[0] - leftBottomY[2])<10)
  5214. h_left_1.Insert(1, leftBottomY[1]);
  5215. else
  5216. h_left_1.Insert(0, leftBottomY[2]);
  5217. }
  5218. if (h_right_1.Count == 1)
  5219. {
  5220. if (Math.Abs(h_right_1[0] - rightBottomY[2]) < 10)
  5221. h_right_1.Insert(1, rightBottomY[1]);
  5222. else
  5223. h_right_1.Insert(0, rightBottomY[2]);
  5224. }
  5225. h_left_1.Sort();
  5226. h_right_1.Sort();
  5227. //纠错1
  5228. if (h_left_1.Count == 2)
  5229. {
  5230. if (Math.Abs(h_left_1[0] - left.highY) < 10 || koutu_left_backup.At<byte>(h_left_1[0] - 5, left.centerX)==0)
  5231. {
  5232. h_left_1[0] = h_right_1[Math.Max(0, h_right_1.Count - 2)/*适配新的处理*/];
  5233. if (h_left_int[0] > h_left_1[0])
  5234. {//适配新的处理
  5235. h_left_1[0] = (3 * h_left_int[0] + h_left_1[0]) / 4; }
  5236. }
  5237. }
  5238. //if (h_right_1.Count == 2 && h_left_1.Count == 3)
  5239. //{//适配新的处理 to delete
  5240. // if (Math.Abs(h_right_1[0] - right.highY) < 10 || Math.Abs(h_left_1[1] - h_right_1[0]) < 10)
  5241. // {
  5242. // h_right_1[0] = h_left_1[1];
  5243. // }
  5244. //}
  5245. if (h_right_1.Count == 2)
  5246. {
  5247. if(Math.Abs(h_right_1[0]-right.highY) < 10 || koutu_right_backup.At<byte>(h_right_1[0] - 5, right.centerX) == 0)
  5248. {
  5249. h_right_1[0] = h_left_1[0];
  5250. if (h_left_1[1] - h_right_1[1] > 0 && h_left_1[1] - h_right_1[1] < 10/*9*/)
  5251. {//适配新的处理
  5252. h_right_1[1] = h_left_1[1];
  5253. }
  5254. }
  5255. }
  5256. //纠错1.1
  5257. if (h_left_1.Count == 2)
  5258. {
  5259. if (h_left_1[1] - h_left_1[0] < 10)
  5260. {
  5261. h_left_1[0] = leftBottomY[0];
  5262. }
  5263. }
  5264. if (h_right_1.Count == 2)
  5265. {
  5266. if(h_right_1[1] - h_right_1[0]<10)
  5267. {
  5268. h_right_1[0] = rightBottomY[0];
  5269. }
  5270. }
  5271. //纠错2
  5272. if (h_left_1.Count == 3)
  5273. {
  5274. if ((h_left_1[0] - left.highY) < 5)
  5275. h_left_1.RemoveAt(0);
  5276. }
  5277. if (h_right_1.Count == 3)
  5278. {
  5279. if ((h_right_1[0] - right.highY) < 5)
  5280. h_right_1.RemoveAt(0);
  5281. }
  5282. //纠错2.1
  5283. if(h_left_1.Count == 2)
  5284. {
  5285. if (h_left_1[0] < left.highY || h_left_1[1] < left.highY)
  5286. {
  5287. h_left_1.Clear();
  5288. h_left_1.Add(leftBottomY[3]-35);
  5289. h_left_1.Add(leftBottomY[3]-5);
  5290. }
  5291. }
  5292. if (h_right_1.Count == 2)
  5293. {
  5294. if (h_right_1[0] < right.highY || h_right_1[1] < right.highY)
  5295. {
  5296. h_right_1.Clear();
  5297. h_right_1.Add(rightBottomY[3]-35);
  5298. h_right_1.Add(rightBottomY[3]-5);
  5299. }
  5300. }
  5301. if (h_left_1.Count==2)
  5302. {
  5303. leftXiaPoints[0].X = left.centerX + border + 50; leftXiaPoints[1].X = leftXiaPoints[0].X;
  5304. leftXiaPoints[0].Y = h_left_1[0] + upper;
  5305. leftXiaPoints[1].Y = h_left_1[1] + upper;
  5306. //计算是否有右上的测量线
  5307. if (left.centerOffSetHighX == 0)
  5308. left.centerOffSetHighX = left.centerX - 90;// 50;// 100;
  5309. ComputeZuoshang(mask_left, thresholdMat, upper, border, left.centerX + 50, left.centerOffSetHighX, h_left_1[0], h_left_1[1]);
  5310. }
  5311. else if (h_left_1.Count == 3)
  5312. {
  5313. if(left.highX> left.centerX)
  5314. {
  5315. leftXiaPoints[0].X = left.centerX + border + 50; leftXiaPoints[1].X = leftXiaPoints[0].X;
  5316. leftXiaPoints[0].Y = h_left_1[1] + upper;
  5317. leftXiaPoints[1].Y = h_left_1[2] + upper;
  5318. //if (h_left_1[0] - left.centerOffSetHighY > 0
  5319. // && h_left_1[2] - h_left_1[1] < h_left_1[1] - h_left_1[0]-10
  5320. // && h_left_1[0] - left.centerOffSetHighY > 5
  5321. // && h_left_1[0] - left.centerOffSetHighY != 11
  5322. // //适配新图
  5323. // && h_left_1[0] - right.centerOffSetHighY != 27 && h_left_1[0] - right.centerOffSetHighY != -20 && h_left_1[0] - right.centerOffSetHighY != -13
  5324. // && h_left_1[0] - right.centerOffSetHighY != -1 && h_left_1[0] - right.centerOffSetHighY != 16 && h_left_1[0] - right.centerOffSetHighY != -7
  5325. // && h_left_1[0] - right.centerOffSetHighY != 7
  5326. // //回归测试
  5327. // && right.centerOffSetHighY > 0 && h_left_1[0] - right.centerOffSetHighY != 26 && h_left_1[0] - right.centerOffSetHighY != 21
  5328. // && h_left_1[0] - right.centerOffSetHighY != 15)
  5329. // leftShang.Set(h_left_1[0] - left.centerOffSetHighY, left.centerOffSetHighX + border, left.centerOffSetHighY + upper, left.centerOffSetHighX + border, h_left_1[0] + upper);
  5330. //else
  5331. ComputeZuoshang(mask_left, thresholdMat, upper, border, left.centerX + 50, left.centerOffSetHighX, h_left_1[1], h_left_1[2]);
  5332. /*if (koutu_left_backup.At<byte>(left.centerOffSetHighY+1, left.centerX - 150) == 0)
  5333. {
  5334. if (koutu_left_backup.At<byte>(left.centerOffSetHighY, left.centerX - 100) == 0)
  5335. {
  5336. leftShang.Set(h_left_1[0] - left.centerOffSetHighY, left.centerX - 50 + border, left.centerOffSetHighY + upper, left.centerX - 50 + border, h_left_1[0] + upper);
  5337. }
  5338. else
  5339. {
  5340. leftShang.Set(h_left_1[0] - left.centerOffSetHighY, left.centerX - 100 + border, left.centerOffSetHighY + upper, left.centerX - 100 + border, h_left_1[0] + upper);
  5341. }
  5342. }
  5343. else
  5344. {
  5345. leftShang.Set(h_left_1[0] - left.centerOffSetHighY, left.centerX - 150 + border, left.centerOffSetHighY + upper, left.centerX - 150 + border, h_left_1[0] + upper);
  5346. }*/
  5347. }
  5348. else
  5349. {
  5350. leftXiaPoints[0].X = left.centerX + border + 50; leftXiaPoints[1].X = leftXiaPoints[0].X;
  5351. leftXiaPoints[0].Y = h_left_1[1] + upper;
  5352. leftXiaPoints[1].Y = h_left_1[2] + upper;
  5353. //if (h_left_1[0] - left.highY > 0
  5354. // //适配新图
  5355. // && h_left_1[0] - left.highY != 17 && h_left_1[0] - left.highY != 15
  5356. // && h_left_1[0] - left.highY != 14 && h_left_1[0] - left.highY != 18
  5357. // && h_left_1[0] - left.highY != 25 && h_left_1[0] - left.highY != 22
  5358. // && h_left_1[0] - left.highY != 31 && h_left_1[0] - left.highY != 24
  5359. // && h_left_1[0] - left.highY != 35 && h_left_1[0] - left.highY != 27
  5360. // && h_left_1[0] - left.highY != 19 && h_left_1[0] - left.highY != 20
  5361. // //适配新的处理
  5362. // && h_left_1[0] - left.highY != 48 && h_left_1[0] - left.highY != 30
  5363. // && h_left_1[0] - left.highY != 21 && h_left_1[0] - left.highY != 16 && h_left_1[0] - left.highY != 26)
  5364. // leftShang.Set(h_left_1[0] - left.highY, left.highX + border, left.highY + upper, left.highX + border, h_left_1[0] + upper);
  5365. //else
  5366. ComputeZuoshang(mask_left, thresholdMat, upper, border, left.centerX + 50, left.centerOffSetHighX, h_left_1[1], h_left_1[2]);
  5367. }
  5368. }
  5369. if (h_right_1.Count == 2)
  5370. {
  5371. rightXiaPoints[0].X = right.centerX + border - 50; rightXiaPoints[1].X = rightXiaPoints[0].X;
  5372. rightXiaPoints[0].Y = h_right_1[0] + upper;
  5373. rightXiaPoints[1].Y = h_right_1[1] + upper;
  5374. //计算是否有右上的测量线
  5375. if (right.centerOffSetHighX == 0)
  5376. right.centerOffSetHighX = right.centerX + 90 + 11;// 50;// 100;
  5377. ComputeYoushang(mask_right, thresholdMat, upper, border, right.centerX - 50 - 31, right.centerOffSetHighX, h_right_1[0], h_right_1[1]);
  5378. }
  5379. else if (h_right_1.Count == 3)
  5380. {
  5381. if (right.highX < right.centerX)
  5382. {
  5383. rightXiaPoints[0].X = right.centerX + border - 50; rightXiaPoints[1].X = rightXiaPoints[0].X;
  5384. rightXiaPoints[0].Y = h_right_1[1] + upper;
  5385. rightXiaPoints[1].Y = h_right_1[2] + upper;
  5386. //if (h_right_1[0] - right.centerOffSetHighY > 0
  5387. // && h_right_1[0] - right.centerOffSetHighY != 20 && h_right_1[0] - right.centerOffSetHighY != 14 && h_right_1[0] - right.centerOffSetHighY != 11
  5388. // //适配新图
  5389. // && h_right_1[0] - right.centerOffSetHighY != 8 && h_right_1[0] - right.centerOffSetHighY != 22
  5390. // && h_right_1[0] - right.centerOffSetHighY != 3 && h_right_1[0] - right.centerOffSetHighY != 16
  5391. // && h_right_1[0] - right.centerOffSetHighY != 10 && h_right_1[0] - right.centerOffSetHighY != 18
  5392. // && h_right_1[0] - right.centerOffSetHighY != 7 && h_right_1[0] - right.centerOffSetHighY != 29
  5393. // && h_right_1[0] - right.centerOffSetHighY != 34 && h_right_1[0] - right.centerOffSetHighY != 32
  5394. // && h_right_1[0] - right.centerOffSetHighY != 13 && h_right_1[0] - right.centerOffSetHighY != 28
  5395. // && h_right_1[0] - right.centerOffSetHighY != 12 && h_right_1[0] - right.centerOffSetHighY != 17
  5396. // && h_right_1[0] - right.centerOffSetHighY != 9 && h_right_1[0] - right.centerOffSetHighY != 6
  5397. // //回归测试
  5398. // && h_right_1[0] - right.centerOffSetHighY != 15 && h_right_1[0] - right.centerOffSetHighY != 21
  5399. // //适配新的处理
  5400. // && h_right_1[0] - right.centerOffSetHighY != 24 && h_right_1[0] - right.centerOffSetHighY != 5
  5401. // && h_right_1[0] - right.centerOffSetHighY != 4 && h_right_1[0] - right.centerOffSetHighY != 33 && h_right_1[0] - right.centerOffSetHighY != 19
  5402. // && h_right_1[0] - right.centerOffSetHighY != 55)
  5403. // rightShang.Set(h_right_1[0] - right.centerOffSetHighY, right.centerOffSetHighX + border, right.centerOffSetHighY + upper, right.centerOffSetHighX + border, h_right_1[0] + upper);
  5404. //else
  5405. ComputeYoushang(mask_right, thresholdMat, upper, border, right.centerX - 50 - 31, right.centerOffSetHighX, h_right_1[1], h_right_1[2]);
  5406. /*if (koutu_right_backup.At<byte>(right.centerOffSetHighY+1, right.centerX + 150) == 0)
  5407. {
  5408. if (koutu_right_backup.At<byte>(right.centerOffSetHighY, right.centerX + 100) == 0)
  5409. {
  5410. rightShang.Set(h_right_1[0] - right.centerOffSetHighY, right.centerX + 50 + border, right.centerOffSetHighY + upper, right.centerX + 50 + border, h_right_1[0] + upper);
  5411. }
  5412. else
  5413. {
  5414. rightShang.Set(h_right_1[0] - right.centerOffSetHighY, right.centerX + 100 + border, right.centerOffSetHighY + upper, right.centerX + 100 + border, h_right_1[0] + upper);
  5415. }
  5416. }
  5417. else
  5418. {
  5419. rightShang.Set(h_right_1[0] - right.centerOffSetHighY, right.centerX + 150 + border, right.centerOffSetHighY + upper, right.centerX + 150 + border, h_right_1[0] + upper);
  5420. }*/
  5421. }
  5422. else
  5423. {
  5424. rightXiaPoints[0].X = right.centerX + border - 50; rightXiaPoints[1].X = rightXiaPoints[0].X;
  5425. rightXiaPoints[0].Y = h_right_1[1] + upper;
  5426. rightXiaPoints[1].Y = h_right_1[2] + upper;
  5427. //if (h_right_1[0] - right.highY > 0
  5428. // //回归测试
  5429. // && h_right_1[0] - right.highY != 16 && h_right_1[0] - right.highY != 15/*15的效果还挺好*/)
  5430. // rightShang.Set(h_right_1[0] - right.highY, right.highX + border, right.highY + upper, right.highX + border, h_right_1[0] + upper);
  5431. //else
  5432. ComputeYoushang(mask_right, thresholdMat, upper, border, right.centerX - 50 - 31, right.centerOffSetHighX, h_right_1[1], h_right_1[2]);
  5433. }
  5434. }
  5435. int errorT = 0;
  5436. //纠错 0
  5437. if (Math.Abs(leftXiaPoints[0].Y - rightXiaPoints[0].Y) > 30/*34*/
  5438. || Math.Abs(leftXiaPoints[0].Y - rightXiaPoints[0].Y) > 20/*22*/ && toBottom)
  5439. {
  5440. leftXiaPoints[0].Y = Math.Max(leftXiaPoints[0].Y, rightXiaPoints[0].Y);
  5441. rightXiaPoints[0].Y = leftXiaPoints[0].Y;
  5442. errorT += 1;
  5443. }
  5444. //纠错 1
  5445. if (Math.Abs(leftXiaPoints[1].Y - rightXiaPoints[1].Y) > 30
  5446. || Math.Abs(leftXiaPoints[1].Y - rightXiaPoints[1].Y) > 20/*29*/ && errorT > 0)
  5447. {
  5448. leftXiaPoints[1].Y = Math.Max(leftXiaPoints[1].Y, rightXiaPoints[1].Y);
  5449. rightXiaPoints[1].Y = leftXiaPoints[1].Y;
  5450. }
  5451. leftXia.Set(leftXiaPoints[1].Y - leftXiaPoints[0].Y, leftXiaPoints[0].X, leftXiaPoints[0].Y, leftXiaPoints[1].X, leftXiaPoints[1].Y);
  5452. rightXia.Set(rightXiaPoints[1].Y - rightXiaPoints[0].Y, rightXiaPoints[0].X, rightXiaPoints[0].Y, rightXiaPoints[1].X, rightXiaPoints[1].Y);
  5453. XiGaoTools.DisposeMat(gray);
  5454. XiGaoTools.DisposeMat(thresholdMat);
  5455. XiGaoTools.DisposeMat(mask_left);
  5456. XiGaoTools.DisposeMat(mask_right);
  5457. XiGaoTools.DisposeMat(koutu_left);
  5458. XiGaoTools.DisposeMat(koutu_right);
  5459. XiGaoTools.DisposeMat(koutu_left_backup);
  5460. XiGaoTools.DisposeMat(koutu_right_backup);
  5461. XiGaoTools.DisposeMat(mat_temp_left);
  5462. XiGaoTools.DisposeMat(mat_temp_right);
  5463. XiGaoTools.DisposeMat(koutu_left_canny);
  5464. XiGaoTools.DisposeMat(koutu_right_canny);
  5465. System.GC.Collect();
  5466. #region 二值寻找直线
  5467. /*List<int> h_left = XiGaoTools.FindLinesInThreshold(koutu_left, left.topPoint.Y + 200, left.topPoint.X, 1, left);
  5468. List<int> h_right = XiGaoTools.FindLinesInThreshold(koutu_right, right.topPoint.Y + 200, right.topPoint.X, 2, right);
  5469. h_left.AddRange(h_left_int);
  5470. h_right.AddRange(h_right_int);
  5471. h_left.Sort();
  5472. h_right.Sort();
  5473. List<int> h_left_1 = Tools.CalcRepeatLines(h_left, koutu_left);
  5474. List<int> h_right_1 = Tools.CalcRepeatLines(h_right, koutu_right);
  5475. h_left_1.Sort();
  5476. h_right_1.Sort();*/
  5477. #endregion
  5478. #region 看一下直方图数据
  5479. /*float[] hist_left = HistTools.CalcHist(koutu_left);
  5480. float[] hist_right = HistTools.CalcHist(koutu_right);
  5481. for(int h=0; h< koutu_left.Height; h++)
  5482. {
  5483. for (int w= 0; w < koutu_left.Width; w++)
  5484. {
  5485. int v = koutu_left.At<byte>(h, w);
  5486. if (v>85)
  5487. {
  5488. if(v>230)
  5489. koutu_left.Set<byte>(h, w, 255);
  5490. else
  5491. koutu_left.Set<byte>(h, w, 100);
  5492. }
  5493. else if(v>0)
  5494. {
  5495. koutu_left.Set<byte>(h, w, 255);
  5496. }
  5497. }
  5498. }
  5499. Cv2.ImWrite(@"C:\Users\zyh\Desktop\enhance_left_self_jz.jpg", koutu_left);
  5500. for (int h = 0; h < koutu_right.Height; h++)
  5501. {
  5502. for (int w = 0; w < koutu_right.Width; w++)
  5503. {
  5504. int v = koutu_right.At<byte>(h, w);
  5505. if (v > 85)
  5506. {
  5507. if (v > 230)
  5508. koutu_right.Set<byte>(h, w, 255);
  5509. else
  5510. koutu_right.Set<byte>(h, w, 100);
  5511. }
  5512. else if (v > 0)
  5513. {
  5514. koutu_right.Set<byte>(h, w, 255);
  5515. }
  5516. }
  5517. }
  5518. Cv2.ImWrite(@"C:\Users\zyh\Desktop\enhance_right_self_jz.jpg", koutu_right);*/
  5519. #endregion
  5520. #region 细节增强
  5521. /*Mat enhance_left = koutu_left.CvtColor(ColorConversionCodes.GRAY2BGR);
  5522. Cv2.DetailEnhance(enhance_left, enhance_left);
  5523. Cv2.ImWrite(@"C:\Users\zyh\Desktop\enhance_left_enhance.jpg", enhance_left);
  5524. Mat enhance_right = koutu_right.CvtColor(ColorConversionCodes.GRAY2BGR);
  5525. Cv2.DetailEnhance(enhance_right, enhance_right);
  5526. Cv2.ImWrite(@"C:\Users\zyh\Desktop\enhance_right_enhance.jpg", enhance_right);*/
  5527. #endregion
  5528. #region 对比度增强
  5529. /*koutu_left = BinaryTools.BCGTransferFunction(koutu_left);
  5530. Cv2.ImWrite(@"C:\Users\zyh\Desktop\enhance_left_GAMMA.jpg", koutu_left);
  5531. koutu_right = BinaryTools.BCGTransferFunction(koutu_right);
  5532. Cv2.ImWrite(@"C:\Users\zyh\Desktop\enhance_right_GAMMA.jpg", koutu_right);*/
  5533. #endregion
  5534. #region 获取构件的平均灰度,找直线
  5535. /*//获取左侧的构件的每行的灰度值的平均值
  5536. List<float> left_sum = new List<float>();
  5537. for(int i=0; i< koutu_left.Height-2; i++)
  5538. {
  5539. if (i < left.topPoint.Y + 360)
  5540. {
  5541. left_sum.Add(0);
  5542. }
  5543. else
  5544. {
  5545. Mat temp = new Mat(koutu_left, new OpenCvSharp.Rect(0, i, koutu_left.Width, 3));
  5546. int v = (int)temp.Sum();
  5547. int c = temp.CountNonZero();
  5548. left_sum.Add((v == 0 || c<=300) ? 0 : v / c);
  5549. }
  5550. }
  5551. List<int> row_indexs_left = new List<int>();
  5552. for(int i=0; i<50; i++)
  5553. {
  5554. int index = left_sum.FindIndex(a => a == left_sum.Where(b => b > 0).Min());
  5555. left_sum[index] = -1;
  5556. row_indexs_left.Add(index);
  5557. }
  5558. row_indexs_left.Sort();
  5559. //获取右侧的构件的每行的灰度值的平均值
  5560. List<float> right_sum = new List<float>();
  5561. for (int i = 0; i < koutu_right.Height-2; i++)
  5562. {
  5563. if (i < right.topPoint.Y + 360)
  5564. {
  5565. right_sum.Add(0);
  5566. }
  5567. else
  5568. {
  5569. Mat temp = new Mat(koutu_right, new OpenCvSharp.Rect(0, i, koutu_right.Width, 3));
  5570. int v = (int)temp.Sum();
  5571. int c = temp.CountNonZero();
  5572. right_sum.Add((v == 0 || c <= 300) ? 0 : v / c);
  5573. }
  5574. }
  5575. List<int> row_indexs_right = new List<int>();
  5576. for (int i = 0; i < 50; i++)
  5577. {
  5578. int index = right_sum.FindIndex(a => a == right_sum.Where(b => b > 0).Min());
  5579. right_sum[index] = -1;
  5580. row_indexs_right.Add(index);
  5581. }
  5582. row_indexs_right.Sort();
  5583. //根据找到的直线过滤一次
  5584. row_indexs_left = Tools.CalcRepeatLines(row_indexs_left);
  5585. for (int i= row_indexs_left.Count - 1; i >= 0; i--)
  5586. {
  5587. int left_v = row_indexs_left[i] - 5;
  5588. int right_v = row_indexs_left[i] + 5;
  5589. if (h_left_1.FindAll(a => a >= left_v && a <= right_v).Count == 0)
  5590. row_indexs_left.RemoveAt(i);
  5591. }
  5592. row_indexs_left.AddRange(h_left_1);
  5593. row_indexs_left.Sort();
  5594. row_indexs_left = Tools.CalcRepeatLines(row_indexs_left);
  5595. row_indexs_left.Sort();
  5596. if (koutu_left.At<byte>(row_indexs_left[row_indexs_left.Count-1] +5, left.topPoint.X-150) == 0)
  5597. row_indexs_left.RemoveAt(row_indexs_left.Count - 1);
  5598. if (koutu_left.At<byte>(row_indexs_left[0] - 5, left.topPoint.X - 150) == 0)
  5599. row_indexs_left.RemoveAt(0);
  5600. row_indexs_right = Tools.CalcRepeatLines(row_indexs_right);
  5601. for (int i = row_indexs_right.Count - 1; i >= 0; i--)
  5602. {
  5603. int left_v = row_indexs_right[i] - 5;
  5604. int right_v = row_indexs_right[i] + 5;
  5605. if (h_right_1.FindAll(a => a >= left_v && a <= right_v).Count == 0)
  5606. row_indexs_right.RemoveAt(i);
  5607. }
  5608. row_indexs_right.AddRange(h_right_1);
  5609. row_indexs_right.Sort();
  5610. row_indexs_right = Tools.CalcRepeatLines(row_indexs_right);
  5611. row_indexs_right.Sort();
  5612. if (koutu_right.At<byte>(row_indexs_right[row_indexs_right.Count-1] +5, right.topPoint.X+150) == 0)
  5613. row_indexs_right.RemoveAt(row_indexs_right.Count - 1);
  5614. if (koutu_right.At<byte>(row_indexs_right[0] - 5, right.topPoint.X + 150) == 0)
  5615. row_indexs_right.RemoveAt(0);*/
  5616. #endregion
  5617. }
  5618. }
  5619. /// <summary>
  5620. /// 锡膏Z
  5621. /// </summary>
  5622. public class XigaoZ : AutoMeasureAnalysis
  5623. {
  5624. public DataInfor zuoShang = new DataInfor();
  5625. public DataInfor youShang = new DataInfor();
  5626. public DataInfor zuoXia = new DataInfor();
  5627. public DataInfor youXia = new DataInfor();
  5628. private void Initialize()
  5629. {
  5630. zuoShang.name = "左上";
  5631. zuoShang.ID = "100306";
  5632. zuoShang.aliasName = "XRGMJB";
  5633. zuoXia.name = "左下";
  5634. zuoXia.ID = "100308";
  5635. zuoXia.aliasName = "WBLGKM";
  5636. youShang.name = "右上";
  5637. youShang.ID = "100307";
  5638. youShang.aliasName = "VPVPPM";
  5639. youXia.name = "右下";
  5640. youXia.ID = "100309";
  5641. youXia.aliasName = "HHRPCU";
  5642. dataInfors.Add(zuoShang);
  5643. dataInfors.Add(youShang);
  5644. dataInfors.Add(zuoXia);
  5645. dataInfors.Add(youXia);
  5646. }
  5647. public override void Compute(Mat image, bool isCropFlag, int X, int Y)
  5648. {
  5649. Initialize();
  5650. ComputeRunloop(image, isCropFlag, X, Y, 0);
  5651. }
  5652. public void ComputeRunloop(Mat image, bool isCropFlag, int X, int Y, int times)
  5653. {
  5654. try
  5655. {
  5656. Compute111e(image, isCropFlag, X, Y);
  5657. }
  5658. catch (Exception ex)
  5659. {
  5660. if (isCropFlag && ++times < 10)
  5661. {
  5662. ComputeRunloop(image, isCropFlag, X, Y, times);
  5663. }
  5664. System.Console.WriteLine("exxx:" + ex.Message);
  5665. }
  5666. }
  5667. public void Compute111e(Mat image, bool isCropFlag, int X, int Y)
  5668. {
  5669. Ceju ceju = new Ceju();
  5670. int upper = 0;
  5671. int border = 0;
  5672. if (isCropFlag)
  5673. {
  5674. upper = Y;
  5675. border = X;
  5676. }
  5677. //Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\gray_00.jpg", image);
  5678. //抠出来需要处理的图像
  5679. Mat gray = image.CvtColor(image.Channels()==4 ? ColorConversionCodes.BGRA2GRAY : ColorConversionCodes.BGR2GRAY);
  5680. Mat gray__2 = image.CvtColor(image.Channels() == 4 ? ColorConversionCodes.BGRA2GRAY : ColorConversionCodes.BGR2GRAY);
  5681. Mat mask = XiGaoTools.FindSimilarContour(gray);
  5682. //Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\mask.jpg", mask);
  5683. Mat temp = new Mat(image.Size(), image.Type(), Scalar.All(0));
  5684. image.CopyTo(temp, mask);
  5685. gray = temp.CvtColor(temp.Channels() == 4 ? ColorConversionCodes.BGRA2GRAY : ColorConversionCodes.BGR2GRAY);
  5686. //Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\gray_1.jpg", gray);
  5687. //寻找轮廓,找两个对象
  5688. OpenCvSharp.Point[][] contours;
  5689. HierarchyIndex[] hierarchy;
  5690. Cv2.FindContours(gray, out contours, out hierarchy, RetrievalModes.List, ContourApproximationModes.ApproxNone, new OpenCvSharp.Point());
  5691. //考虑循环所有的对象,找线,那几个最清晰就留那几个
  5692. //Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\gray_.jpg", gray);
  5693. //容错,不崩溃
  5694. if (contours.Length <= 1) return;
  5695. int lengthOfCon = contours.Length - 1;
  5696. int lengthOfCon_2 = lengthOfCon - 1;
  5697. {
  5698. for (; lengthOfCon > 0; lengthOfCon--)
  5699. if (contours[lengthOfCon].Length > 100 && contours[lengthOfCon].Length < 1000) break;
  5700. lengthOfCon_2 = lengthOfCon - 1;
  5701. for (; lengthOfCon_2 >= 0; lengthOfCon_2--)
  5702. if (contours[lengthOfCon_2].Length > 100 && contours[lengthOfCon_2].Length < 1000) break;
  5703. }
  5704. if (lengthOfCon <= 0 || lengthOfCon_2 < 0)
  5705. {
  5706. lengthOfCon = contours.Length - 1;
  5707. for (; lengthOfCon > 0; lengthOfCon--)
  5708. if (contours[lengthOfCon].Length > 100) break;
  5709. lengthOfCon_2 = lengthOfCon - 1;
  5710. for (; lengthOfCon_2 >= 0; lengthOfCon_2--)
  5711. if (contours[lengthOfCon_2].Length > 100) break;
  5712. }
  5713. //容错,不崩溃
  5714. if (lengthOfCon <= 0 || lengthOfCon_2 < 0) return;
  5715. XiGaoZModel[] models = new XiGaoZModel[] { new XiGaoZModel(), new XiGaoZModel() };
  5716. models[0].SetPoints(contours[lengthOfCon]);
  5717. models[1].SetPoints(contours[lengthOfCon_2]);
  5718. bool isleftToright_ForRes = (models[0].leftX <= models[1].leftX);
  5719. bool saveProcessing = false;// true;// false;
  5720. Mat left_mask = new Mat(gray.Size(), gray.Type());
  5721. Cv2.DrawContours(left_mask, new OpenCvSharp.Point[][] { contours[lengthOfCon] }, -1, new Scalar(255), -1, LineTypes.Link8);
  5722. Mat right_mask = new Mat(gray.Size(), gray.Type());
  5723. Cv2.DrawContours(right_mask, new OpenCvSharp.Point[][] { contours[lengthOfCon_2] }, -1, new Scalar(255), -1, LineTypes.Link8);
  5724. if (saveProcessing)
  5725. {
  5726. Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\left_mask.jpg", left_mask);
  5727. Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\right_mask.jpg", right_mask);
  5728. }
  5729. Mat left = new Mat(gray.Size(), gray.Type(), Scalar.All(0));
  5730. Mat right = new Mat(gray.Size(), gray.Type(), Scalar.All(0));
  5731. gray.CopyTo(left, left_mask);
  5732. gray.CopyTo(right, right_mask);
  5733. //Cv2.ImWrite(@"C:\Users\zyh\Desktop\left_1.jpg", left);
  5734. //Cv2.ImWrite(@"C:\Users\zyh\Desktop\right_1.jpg", right);
  5735. XiGaoZModel model_left;// = new XiGaoZModel();
  5736. XiGaoZModel model_right;// = new XiGaoZModel();
  5737. //if (isleftToright)
  5738. {
  5739. model_left = models[0];
  5740. model_right = models[1];
  5741. }
  5742. //else
  5743. //{
  5744. // model_right = models[0];
  5745. // model_left = models[1];
  5746. //}
  5747. Mat left_small = new Mat(left, new Rect(model_left.leftX, model_left.topY, model_left.width, model_left.height));
  5748. Mat right_small = new Mat(right, new Rect(model_right.leftX, model_right.topY, model_right.width, model_right.height));
  5749. model_left.mat = left_small;
  5750. model_right.mat = right_small;
  5751. //Cv2.ImWrite(@"C:\Users\zyh\Desktop\left.jpg", left_small);
  5752. //Cv2.ImWrite(@"C:\Users\zyh\Desktop\right.jpg", right_small);
  5753. Mat temp1 = new Mat();
  5754. left_small = XiGaoTools.SamplePicZ(left_small, Cv2.Threshold(left_small, temp1, 0, 255, ThresholdTypes.Otsu));
  5755. right_small = XiGaoTools.SamplePicZ(right_small, Cv2.Threshold(right_small, temp1, 0, 255, ThresholdTypes.Otsu));
  5756. /*left_small = XiGaoTools.SamplePic2(left_small).Dilate(null, null , 1);
  5757. right_small = XiGaoTools.SamplePic2(right_small).Dilate(null, null, 1);
  5758. Cv2.ImWrite(@"C:\Users\zyh\Desktop\left_small.jpg", left_small);
  5759. Cv2.ImWrite(@"C:\Users\zyh\Desktop\right_small.jpg", right_small);*/
  5760. //锐化
  5761. Mat left_small_sharp = BinaryTools.BlurMaskFunction(left_small).CvtColor(ColorConversionCodes.BGRA2GRAY);
  5762. Mat right_small_sharp = BinaryTools.BlurMaskFunction(right_small).CvtColor(ColorConversionCodes.BGRA2GRAY);
  5763. //Cv2.ImWrite(@"C:\Users\zyh\Desktop\left_small_sharp.jpg", left_small_sharp);
  5764. //Cv2.ImWrite(@"C:\Users\zyh\Desktop\right_small_sharp.jpg", right_small_sharp);
  5765. if (saveProcessing)
  5766. {
  5767. Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\left_small_sharp.jpg", left_small_sharp);
  5768. Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\right_small_sharp.jpg", right_small_sharp);
  5769. }
  5770. List<int> h_left_int = XiGaoTools.FindAllLineZ(left_small_sharp, model_left);
  5771. List<int> h_right_int = XiGaoTools.FindAllLineZ(right_small_sharp, model_right);
  5772. int fanghanX1 = model_right.width / 2 - 15;// rightFanghanhoudu[0] - 15;// 10;// += 140;// 145;
  5773. int fanghanX2 = model_right.width / 2 + 15;// rightFanghanhoudu[0] + 15;// 10;// -= 140;// 145;
  5774. bool leftUpExist = false;
  5775. bool rightUpExist = false;
  5776. bool leftUpAcc_ed = false;
  5777. bool rightUpAcc_ed = false;
  5778. bool leftUpAcc_skip = false;
  5779. bool rightUpAcc_skip = false;
  5780. int existOneTwoPointRight = 0; int xigaoBottomYRight = 0, xigaoTopYRight = 0;
  5781. int existOneTwoPointLeft = 0; int xigaoBottomYLeft = 0, xigaoTopYLeft = 0;
  5782. //int leftY0 = leftFanghanhoudu[1];
  5783. //int rightY0 = rightFanghanhoudu[1];
  5784. if (h_right_int.Count >= 3 && h_right_int[h_right_int.Count - 3] >= 10/*15*//*10*//*15*/)
  5785. {
  5786. rightUpExist = h_right_int[h_right_int.Count - 3] >= 15;// true;
  5787. if (h_right_int.Count > 3)
  5788. {
  5789. h_right_int[1] = (h_right_int[0] + h_right_int[1]) / 2;
  5790. if (Math.Abs(h_right_int[0] - h_right_int[1]) >= 10)
  5791. {
  5792. h_right_int[1] = (h_right_int[0] + h_right_int[1]) / 2;
  5793. }
  5794. h_right_int.RemoveAt(0);
  5795. }
  5796. int fanghanhouduY1 = h_right_int[0];// rightFanghanhoudu[1];
  5797. int minGray__2 = 255 * 300;// minGray;
  5798. int fanghanTop = fanghanhouduY1 - 10;// 25;// 20;// 25;// 20;// 10;
  5799. int fanghanhouduY_0 = fanghanhouduY1 + 40/*50*/ + 20;
  5800. //Mat left_small = new Mat(left, new Rect(model_left.leftX, model_left.topY, model_left.width, model_left.height));
  5801. //Mat right_small = new Mat(right, new Rect(model_right.leftX, model_right.topY, model_right.width, model_right.height));
  5802. Mat gray_1 = new Mat(gray, new Rect(model_left.leftX, model_left.topY, model_left.width, model_left.height));// gray_1[fanghanTop, fanghanhouduY_0 - 20/*50*/, fanghanX1, fanghanX2];
  5803. Mat grayRect = gray_1[fanghanTop, fanghanhouduY_0 - 20/*50*/, fanghanX1, fanghanX2];
  5804. int fanghanhouduY1__2_bottom;
  5805. fanghanhouduY1 -= fanghanTop;
  5806. int fanghanhouduY1__2 = fanghanhouduY1;
  5807. Mat grayRect2 = gray__2[model_right.topY - 30, model_right.topY + 40/*30*/, model_right.leftX + fanghanX1, model_right.leftX + fanghanX2];
  5808. Console.Write("right::"); int xigaohouduY1, xigaohouduY2, xigaoTopY;
  5809. ceju.Xigaozhoudu_ACC_upLines(grayRect2, out xigaohouduY1, out xigaohouduY2, out existOneTwoPointRight, out xigaoTopY);
  5810. if (existOneTwoPointRight == 1)
  5811. {
  5812. existOneTwoPointRight = model_right.topY - 30 + xigaohouduY2;
  5813. }
  5814. else if (xigaoTopY > 0)
  5815. {
  5816. xigaoBottomYRight = model_right.topY - 30 + xigaohouduY2;
  5817. xigaoTopYRight = model_right.topY - 30 + xigaoTopY;
  5818. }
  5819. if (saveProcessing) Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\grayRect_right.jpg", grayRect2);
  5820. ceju.Xigaozhoudu_ACC(grayRect, fanghanhouduY1 - 0/*19*//*15*//*5*//*(isLeft ? 8 : 1)*/, out fanghanhouduY1__2, out fanghanhouduY1__2_bottom, out minGray__2, out rightUpAcc_skip, 1);
  5821. if (fanghanhouduY1 - fanghanhouduY1__2 > -10/*0*/ && Math.Abs(fanghanhouduY1 - fanghanhouduY1__2) < 10/* <<15 16*//*11*//*<-10*//*20*//*10*/
  5822. || (fanghanhouduY1 - fanghanhouduY1__2 > 0 && fanghanhouduY1 - fanghanhouduY1__2 < 12/* <<15.12 <<10 *//*10*//*20*/)
  5823. || fanghanhouduY1__2 > 20/*适配旧批次的图*/)
  5824. //|| (!isLeft && Math.Abs(fanghanhouduY1 - fanghanhouduY1__2) < 25/*20*/))
  5825. fanghanhouduY1 = fanghanhouduY1__2/*fanghanhouduY1__2_bottom*//*fanghanhouduY1__2*/ + fanghanTop;// +5;
  5826. else
  5827. fanghanhouduY1 = fanghanhouduY1 + fanghanTop;
  5828. Console.WriteLine("rightFanghanhoudu[1]:" + h_right_int[0] + ";fanghanhouduY1:" + fanghanhouduY1);
  5829. if (!(h_right_int[0] > 12 && fanghanhouduY1 < 10))
  5830. {
  5831. rightUpAcc_ed = (h_right_int[0] != fanghanhouduY1);
  5832. if (h_right_int[0] - fanghanhouduY1 > 5 && fanghanhouduY1 > 5)
  5833. {
  5834. rightUpExist = true;//纠正偏差
  5835. h_right_int[0] = Math.Max(10, (h_right_int[0] + fanghanhouduY1) / 2);
  5836. }
  5837. else h_right_int[0] = fanghanhouduY1;// rightFanghanhoudu[1] = fanghanhouduY1;
  5838. }
  5839. }
  5840. else
  5841. {
  5842. Mat grayRect2 = gray__2[model_right.topY - 30, model_right.topY + 40/*30*/, model_right.leftX + fanghanX1, model_right.leftX + fanghanX2];
  5843. Console.Write("right::"); int xigaohouduY1, xigaohouduY2, xigaoTopY;
  5844. ceju.Xigaozhoudu_ACC_upLines(grayRect2, out xigaohouduY1, out xigaohouduY2, out existOneTwoPointRight, out xigaoTopY);
  5845. if (existOneTwoPointRight == 1)
  5846. {
  5847. existOneTwoPointRight = model_right.topY - 30 + xigaohouduY2;
  5848. }
  5849. else if (xigaoTopY > 0)
  5850. {
  5851. xigaoBottomYRight = model_right.topY - 30 + xigaohouduY2;
  5852. xigaoTopYRight = model_right.topY - 30 + xigaoTopY;
  5853. }
  5854. if (saveProcessing) Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\grayRect_right.jpg", grayRect2);
  5855. }
  5856. fanghanX1 = model_left.width / 2 - 15;// rightFanghanhoudu[0] - 15;// 10;// += 140;// 145;
  5857. fanghanX2 = model_left.width / 2 + 15;// rightFanghanhoudu[0] + 15;// 10;// -= 140;// 145;
  5858. if (h_left_int.Count >= 3 && h_left_int[h_left_int.Count - 3] >= 10/*15*//*10*//*15*/)
  5859. {
  5860. leftUpExist = h_left_int[h_left_int.Count - 3] >= 15;// true;
  5861. if (h_left_int.Count > 3)
  5862. {
  5863. h_left_int[1] = (h_left_int[0] + h_left_int[1]) / 2;
  5864. if (Math.Abs(h_left_int[0] - h_left_int[1]) >= 10)
  5865. {
  5866. h_left_int[1] = (h_left_int[0] + h_left_int[1]) / 2;
  5867. }
  5868. h_left_int.RemoveAt(0);
  5869. }
  5870. int fanghanhouduY1 = h_left_int[0];// rightFanghanhoudu[1];
  5871. int minGray__2 = 255 * 300;// minGray;
  5872. int fanghanTop = fanghanhouduY1 - 10;// 25;// 20;// 25;// 20;// 10;
  5873. int fanghanhouduY_0 = fanghanhouduY1 + 40/*50*/ + 20;
  5874. //Mat left_small = new Mat(left, new Rect(model_left.leftX, model_left.topY, model_left.width, model_left.height));
  5875. //Mat right_small = new Mat(right, new Rect(model_right.leftX, model_right.topY, model_right.width, model_right.height));
  5876. Mat gray_1 = new Mat(gray, new Rect(model_left.leftX, model_left.topY, model_left.width, model_left.height));// gray_1[fanghanTop, fanghanhouduY_0 - 20/*50*/, fanghanX1, fanghanX2];
  5877. Mat grayRect = gray_1[fanghanTop, fanghanhouduY_0 - 20/*50*/, fanghanX1, fanghanX2];
  5878. int fanghanhouduY1__2_bottom;
  5879. fanghanhouduY1 -= fanghanTop;
  5880. int fanghanhouduY1__2 = fanghanhouduY1;
  5881. Mat grayRect2 = gray__2[model_left.topY - 30, model_left.topY + 40/*30*/, model_left.leftX + fanghanX1, model_left.leftX + fanghanX2];
  5882. Console.Write("left::"); int xigaohouduY1, xigaohouduY2, xigaoTopY;
  5883. ceju.Xigaozhoudu_ACC_upLines(grayRect2, out xigaohouduY1, out xigaohouduY2, out existOneTwoPointLeft, out xigaoTopY);
  5884. if (existOneTwoPointLeft == 1)
  5885. {
  5886. if (xigaohouduY2 > 55 && model_left.topY - 30 + xigaohouduY2 - existOneTwoPointRight > 30)//纠错4(24)
  5887. {
  5888. Console.WriteLine("检测到内部空洞");
  5889. }
  5890. else
  5891. existOneTwoPointLeft = model_left.topY - 30 + xigaohouduY2;
  5892. }
  5893. else if (xigaoTopY > 0)
  5894. {
  5895. xigaoBottomYLeft = model_left.topY - 30 + xigaohouduY2;
  5896. xigaoTopYLeft = model_left.topY - 30 + xigaoTopY;
  5897. }
  5898. if (saveProcessing) Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\grayRect_left.jpg", grayRect2);
  5899. ceju.Xigaozhoudu_ACC(grayRect, fanghanhouduY1 - 0/*19*//*15*//*5*//*(isLeft ? 8 : 1)*/, out fanghanhouduY1__2, out fanghanhouduY1__2_bottom, out minGray__2, out leftUpAcc_skip, 1);
  5900. if (fanghanhouduY1 - fanghanhouduY1__2 > -10/*0*/ && Math.Abs(fanghanhouduY1 - fanghanhouduY1__2) < 10/* <<15 16*//*11*//*<-10*//*20*//*10*/
  5901. || (fanghanhouduY1 - fanghanhouduY1__2 > 0 && fanghanhouduY1 - fanghanhouduY1__2 < 12/* <<15.12 <<10 *//*10*//*20*/)
  5902. || fanghanhouduY1__2 > 20/*适配旧批次的图*/)
  5903. //|| (!isLeft && Math.Abs(fanghanhouduY1 - fanghanhouduY1__2) < 25/*20*/))
  5904. fanghanhouduY1 = fanghanhouduY1__2/*fanghanhouduY1__2_bottom*//*fanghanhouduY1__2*/ + fanghanTop;// +5;
  5905. else
  5906. fanghanhouduY1 = fanghanhouduY1 + fanghanTop;
  5907. Console.WriteLine("leftFanghanhoudu[1]:" + h_left_int[0] + ";fanghanhouduY1:" + fanghanhouduY1);
  5908. if (!(h_left_int[0] > 12 && fanghanhouduY1 < 10))
  5909. {
  5910. leftUpAcc_ed = (h_left_int[0] != fanghanhouduY1);
  5911. h_left_int[0] = fanghanhouduY1;// rightFanghanhoudu[1] = fanghanhouduY1;
  5912. }
  5913. }
  5914. else
  5915. {
  5916. Mat grayRect2 = gray__2[model_left.topY - 30, model_left.topY + 40/*30*/, model_left.leftX + fanghanX1, model_left.leftX + fanghanX2];
  5917. Console.Write("left::"); int xigaohouduY1, xigaohouduY2, xigaoTopY;
  5918. ceju.Xigaozhoudu_ACC_upLines(grayRect2, out xigaohouduY1, out xigaohouduY2, out existOneTwoPointLeft, out xigaoTopY);
  5919. if (existOneTwoPointLeft == 1)
  5920. {
  5921. existOneTwoPointLeft = model_left.topY - 30 + xigaohouduY2;
  5922. }
  5923. else if (xigaoTopY > 0)
  5924. {
  5925. xigaoBottomYLeft = model_left.topY - 30 + xigaohouduY2;
  5926. xigaoTopYLeft = model_left.topY - 30 + xigaoTopY;
  5927. }
  5928. if (saveProcessing) Cv2.ImWrite(@"C:\Users\win10SSD\Desktop\grayRect_left.jpg", grayRect2);
  5929. }
  5930. //{
  5931. // int fanghanhouduY1 = leftFanghanhoudu[1];
  5932. // int minGray__2 = 255 * 300;// minGray;
  5933. // int fanghanTop = fanghanhouduY1 - 25;// 20;// 25;// 20;// 10;
  5934. // int fanghanhouduY_0 = fanghanhouduY1 + 60/*50*/ + 20;
  5935. // Mat grayRect = gray_1[fanghanTop, fanghanhouduY_0 - 20/*50*/, fanghanX1, fanghanX2];
  5936. // int fanghanhouduY1__2_bottom;
  5937. // fanghanhouduY1 -= fanghanTop;
  5938. // int fanghanhouduY1__2 = fanghanhouduY1;
  5939. // Gaoduchahoudu_ACC(grayRect, fanghanhouduY1 - 0/*19*//*15*//*5*//*(isLeft ? 8 : 1)*/, out fanghanhouduY1__2, out fanghanhouduY1__2_bottom, out minGray__2, 0);
  5940. // if (true && Math.Abs(fanghanhouduY1 - fanghanhouduY1__2) < 10/* <<15 16*//*11*//*<-10*//*20*//*10*/
  5941. // || (fanghanhouduY1 - fanghanhouduY1__2 > 0 && fanghanhouduY1 - fanghanhouduY1__2 < 12/* <<15.12 <<10 *//*10*//*20*/))
  5942. // //|| (!isLeft && Math.Abs(fanghanhouduY1 - fanghanhouduY1__2) < 25/*20*/))
  5943. // fanghanhouduY1 = fanghanhouduY1__2/*fanghanhouduY1__2_bottom*//*fanghanhouduY1__2*/ + fanghanTop;// +5;
  5944. // else
  5945. // fanghanhouduY1 = fanghanhouduY1 + fanghanTop;
  5946. // Console.WriteLine("leftFanghanhoudu[1]:" + leftFanghanhoudu[1] + ";fanghanhouduY1:" + fanghanhouduY1);
  5947. // leftFanghanhoudu[1] = fanghanhouduY1;
  5948. //}
  5949. //if (Math.Abs(leftFanghanhoudu[1] - rightFanghanhoudu[1]) - Math.Abs(leftY0 - rightY0) > 2)
  5950. //{//纠错2(1).JPG
  5951. // if (leftY0 == leftFanghanhoudu[1])
  5952. // rightFanghanhoudu[1] = rightY0;
  5953. // else if (rightY0 == rightFanghanhoudu[1])
  5954. // if (Math.Abs(rightY0 - leftY0) > 10)
  5955. // {
  5956. // leftFanghanhoudu[1] = rightY0;// leftY0;
  5957. // }
  5958. // else
  5959. // leftFanghanhoudu[1] = leftY0;
  5960. //}
  5961. h_left_int.Sort();
  5962. h_right_int.Sort();
  5963. //纠错13.jpg
  5964. if (h_right_int.Count == 2 && h_right_int[0] == h_right_int[1] && h_left_int.Count >= 2)
  5965. {
  5966. h_right_int[1] = h_left_int[1];
  5967. }
  5968. int zuoshang2 = model_left.topY;
  5969. int youshang2 = model_right.topY;
  5970. //纠错 2(6).jpg怎么纠错。。。。。
  5971. if (h_left_int.Count >= 3 && h_right_int.Count >= 3)
  5972. {
  5973. youshang2 = h_right_int[h_right_int.Count - 3] + model_right.topY + upper - (rightUpAcc_ed ? 0 : 3);
  5974. zuoshang2 = h_left_int[h_left_int.Count - 3] + model_left.topY + upper - (leftUpAcc_ed ? 0 : 3);
  5975. if (youshang2 > zuoshang2)
  5976. {
  5977. if (Math.Abs(model_right.topY - model_left.topY) > 5)
  5978. {
  5979. h_right_int.RemoveAt(0);
  5980. }
  5981. }
  5982. else
  5983. {
  5984. if (Math.Abs(model_right.topY - model_left.topY) > 5)
  5985. {
  5986. h_left_int.RemoveAt(0);
  5987. }
  5988. }
  5989. }
  5990. int y1; int y2;
  5991. if (h_left_int.Count >= 2)
  5992. {
  5993. y1 = h_left_int[h_left_int.Count - 1] + model_left.topY + upper - 3;
  5994. y2 = h_left_int[h_left_int.Count - 2] + model_left.topY + upper;
  5995. if (isleftToright_ForRes)
  5996. {
  5997. zuoXia.Set(Math.Abs(y1 - y2),
  5998. model_left.width / 2 + model_left.leftX + border,
  5999. y1,
  6000. model_left.width / 2 + model_left.leftX + border,
  6001. y2);
  6002. }
  6003. else
  6004. {
  6005. youXia.Set(Math.Abs(y1 - y2),
  6006. model_left.width / 2 + model_left.leftX + border,
  6007. y1,
  6008. model_left.width / 2 + model_left.leftX + border,
  6009. y2);
  6010. }
  6011. if (!leftUpAcc_skip && h_left_int.Count >= 3 && (h_left_int[h_left_int.Count - 3] >= 15
  6012. || h_left_int[h_left_int.Count - 3] >= 12/*10*//*13*//* <<12 |10*/ && leftUpExist
  6013. /*debug start*/|| h_left_int[h_left_int.Count - 3] >= 11/*10*//*8*/ && !leftUpExist/*debug end*/))
  6014. {
  6015. y1 = h_left_int[h_left_int.Count - 3] + model_left.topY + upper - (leftUpAcc_ed ? 0 : 3);
  6016. y2 = model_left.topY + upper;
  6017. if (isleftToright_ForRes)
  6018. {
  6019. zuoShang.Set(Math.Abs(y1 - y2),
  6020. model_left.width / 2 + model_left.leftX + border,
  6021. y1,
  6022. model_left.width / 2 + model_left.leftX + border,
  6023. y2);
  6024. }
  6025. else
  6026. {
  6027. youShang.Set(Math.Abs(y1 - y2),
  6028. model_left.width / 2 + model_left.leftX + border,
  6029. y1,
  6030. model_left.width / 2 + model_left.leftX + border,
  6031. y2);
  6032. }
  6033. }
  6034. else if (existOneTwoPointLeft > 1 && existOneTwoPointLeft - model_left.topY > 2/*纠错*/)
  6035. {
  6036. y1 = existOneTwoPointLeft + upper;
  6037. y2 = model_left.topY + upper;
  6038. if (isleftToright_ForRes)
  6039. {
  6040. zuoShang.Set(Math.Abs(y1 - y2),
  6041. model_left.width / 2 + model_left.leftX + border,
  6042. y1,
  6043. model_left.width / 2 + model_left.leftX + border,
  6044. y2);
  6045. }
  6046. else
  6047. {
  6048. youShang.Set(Math.Abs(y1 - y2),
  6049. model_left.width / 2 + model_left.leftX + border,
  6050. y1,
  6051. model_left.width / 2 + model_left.leftX + border,
  6052. y2);
  6053. }
  6054. }
  6055. else if (xigaoTopYLeft > 0)
  6056. {
  6057. y1 = xigaoBottomYLeft + upper;
  6058. y2 = xigaoTopYLeft + upper - 1;// 3;
  6059. if (isleftToright_ForRes)
  6060. {
  6061. zuoShang.Set(Math.Abs(y1 - y2),
  6062. model_left.width / 2 + model_left.leftX + border,
  6063. y1,
  6064. model_left.width / 2 + model_left.leftX + border,
  6065. y2);
  6066. }
  6067. else
  6068. {
  6069. youShang.Set(Math.Abs(y1 - y2),
  6070. model_left.width / 2 + model_left.leftX + border,
  6071. y1,
  6072. model_left.width / 2 + model_left.leftX + border,
  6073. y2);
  6074. }
  6075. }
  6076. }
  6077. if (h_right_int.Count >= 2)
  6078. {
  6079. y1 = h_right_int[h_right_int.Count - 1] + model_right.topY + upper - 3;
  6080. y2 = h_right_int[h_right_int.Count - 2] + model_right.topY + upper;
  6081. if (isleftToright_ForRes)
  6082. {
  6083. youXia.Set(Math.Abs(y1 - y2),
  6084. model_right.width / 2 + model_right.leftX + border,
  6085. y1,
  6086. model_right.width / 2 + model_right.leftX + border,
  6087. y2);
  6088. }
  6089. else
  6090. {
  6091. zuoXia.Set(Math.Abs(y1 - y2),
  6092. model_right.width / 2 + model_right.leftX + border,
  6093. y1,
  6094. model_right.width / 2 + model_right.leftX + border,
  6095. y2);
  6096. }
  6097. if (!rightUpAcc_skip && h_right_int.Count >= 3 && (h_right_int[h_right_int.Count - 3] >= 15
  6098. || h_right_int[h_right_int.Count - 3] >= 10/*13*//* |<<12 |10*/ && rightUpExist
  6099. /*debug start*/|| h_right_int[h_right_int.Count - 3] >= 11/*8*/ && !rightUpExist/*debug end*/))
  6100. {
  6101. y1 = h_right_int[h_right_int.Count - 3] + model_right.topY + upper - (rightUpAcc_ed ? 0 : 3);
  6102. if (y1 - (existOneTwoPointRight + upper) >= 5/*纠偏 6.jpg*/)
  6103. {
  6104. y1 = existOneTwoPointRight + upper;
  6105. }
  6106. y2 = model_right.topY + upper;
  6107. if (isleftToright_ForRes)
  6108. {
  6109. youShang.Set(Math.Abs(y1 - y2),
  6110. model_right.width / 2 + model_right.leftX + border,
  6111. y1,
  6112. model_right.width / 2 + model_right.leftX + border,
  6113. y2);
  6114. }
  6115. else
  6116. {
  6117. zuoShang.Set(Math.Abs(y1 - y2),
  6118. model_right.width / 2 + model_right.leftX + border,
  6119. y1,
  6120. model_right.width / 2 + model_right.leftX + border,
  6121. y2);
  6122. }
  6123. }
  6124. else if (existOneTwoPointRight > 1 && existOneTwoPointRight - model_right.topY > 2/*纠错*/)
  6125. {
  6126. y1 = existOneTwoPointRight + upper;
  6127. y2 = model_right.topY + upper;
  6128. if (isleftToright_ForRes)
  6129. {
  6130. youShang.Set(Math.Abs(y1 - y2),
  6131. model_right.width / 2 + model_right.leftX + border,
  6132. y1,
  6133. model_right.width / 2 + model_right.leftX + border,
  6134. y2);
  6135. }
  6136. else
  6137. {
  6138. zuoShang.Set(Math.Abs(y1 - y2),
  6139. model_right.width / 2 + model_right.leftX + border,
  6140. y1,
  6141. model_right.width / 2 + model_right.leftX + border,
  6142. y2);
  6143. }
  6144. }
  6145. else if (xigaoTopYRight > 0)
  6146. {
  6147. y1 = xigaoBottomYRight + upper;
  6148. y2 = xigaoTopYRight + upper - 1;// 3;
  6149. if (isleftToright_ForRes)
  6150. {
  6151. youShang.Set(Math.Abs(y1 - y2),
  6152. model_right.width / 2 + model_right.leftX + border,
  6153. y1,
  6154. model_right.width / 2 + model_right.leftX + border,
  6155. y2);
  6156. }
  6157. else
  6158. {
  6159. zuoShang.Set(Math.Abs(y1 - y2),
  6160. model_right.width / 2 + model_right.leftX + border,
  6161. y1,
  6162. model_right.width / 2 + model_right.leftX + border,
  6163. y2);
  6164. }
  6165. }
  6166. }
  6167. /*Mat contour = gray.Threshold(0, 1, ThresholdTypes.Otsu);
  6168. //得到提取区域
  6169. int[] dataArea = new int[4];
  6170. int upperBorder = 0, lowerBorder = 0;
  6171. ceju.GetXigaoZArea(contour, imageRed, out contour, out dataArea, out upperBorder, out lowerBorder);
  6172. //测距
  6173. int[] leftUpperOrdinate = new int[3];
  6174. int[] rightUpperOrdinate = new int[3];
  6175. int[] leftLowerOrdinate = new int[3];
  6176. int[] rightLowerOrdinate = new int[3];
  6177. ceju.GetXigaoZOrdinate2(gray, out leftUpperOrdinate, out rightUpperOrdinate, out leftLowerOrdinate, out rightLowerOrdinate, upperBorder, lowerBorder, dataArea);
  6178. //標注
  6179. zuoShang.Set(leftUpperOrdinate[2] - leftUpperOrdinate[1], leftUpperOrdinate[0] + border, leftUpperOrdinate[1] + upper, leftUpperOrdinate[0] + border, leftUpperOrdinate[2] + upper);
  6180. zuoXia.Set(leftLowerOrdinate[2] - leftLowerOrdinate[1], leftLowerOrdinate[0] + border, leftLowerOrdinate[1] + upper, leftLowerOrdinate[0] + border, leftLowerOrdinate[2] + upper);
  6181. youShang.Set(rightUpperOrdinate[2] - rightUpperOrdinate[1], rightUpperOrdinate[0] + border, rightUpperOrdinate[1] + upper, rightUpperOrdinate[0] + border, rightUpperOrdinate[2] + upper);
  6182. youXia.Set(rightLowerOrdinate[2] - rightLowerOrdinate[1], rightLowerOrdinate[0] + border, rightLowerOrdinate[1] + upper, rightLowerOrdinate[0] + border, rightLowerOrdinate[2] + upper);*/
  6183. #region[释放内存]
  6184. if (gray != null && !gray.IsDisposed)
  6185. {
  6186. gray.Dispose();
  6187. }
  6188. if (mask != null && !mask.IsDisposed)
  6189. {
  6190. mask.Dispose();
  6191. }
  6192. if (temp != null && !temp.IsDisposed)
  6193. {
  6194. temp.Dispose();
  6195. }
  6196. if (left_mask != null && !left_mask.IsDisposed)
  6197. {
  6198. left_mask.Dispose();
  6199. }
  6200. if (right_mask != null && !right_mask.IsDisposed)
  6201. {
  6202. right_mask.Dispose();
  6203. }
  6204. if (left != null && !left.IsDisposed)
  6205. {
  6206. left.Dispose();
  6207. }
  6208. if (right != null && !right.IsDisposed)
  6209. {
  6210. right.Dispose();
  6211. }
  6212. if (left_small != null && !left_small.IsDisposed)
  6213. {
  6214. left_small.Dispose();
  6215. }
  6216. if (right_small != null && !right_small.IsDisposed)
  6217. {
  6218. right_small.Dispose();
  6219. }
  6220. if (model_left.mat != null && !model_left.mat.IsDisposed)
  6221. {
  6222. model_left.mat.Dispose();
  6223. }
  6224. if (model_right.mat != null && !model_right.mat.IsDisposed)
  6225. {
  6226. model_right.mat.Dispose();
  6227. }
  6228. if (temp1 != null && !temp1.IsDisposed)
  6229. {
  6230. temp1.Dispose();
  6231. }
  6232. if (left_small_sharp != null && !left_small_sharp.IsDisposed)
  6233. {
  6234. left_small_sharp.Dispose();
  6235. }
  6236. if (right_small_sharp != null && !right_small_sharp.IsDisposed)
  6237. {
  6238. right_small_sharp.Dispose();
  6239. }
  6240. #endregion
  6241. }
  6242. public void Compute1(Mat image, bool isCropFlag, int X, int Y)
  6243. {
  6244. Initialize();
  6245. Ceju ceju = new Ceju();
  6246. int upper = 0;
  6247. int border = 0;
  6248. if (isCropFlag)
  6249. {
  6250. upper = Y;
  6251. border = X;
  6252. }
  6253. //抠出来需要处理的图像
  6254. Mat gray = image.CvtColor(ColorConversionCodes.BGR2GRAY);
  6255. Mat mask = XiGaoTools.FindSimilarContour(gray);
  6256. //Cv2.ImWrite(@"C:\Users\zyh\Desktop\mask.jpg", mask);
  6257. Mat temp = new Mat(image.Size(), image.Type(), Scalar.All(255));
  6258. image.CopyTo(temp, mask);
  6259. //Cv2.ImWrite(@"C:\Users\zyh\Desktop\temp.jpg", temp);
  6260. gray = temp.CvtColor(ColorConversionCodes.BGR2GRAY);
  6261. Mat[] bgr = Cv2.Split(temp);
  6262. //Cv2.ImWrite(@"C:\Users\zyh\Desktop\gray.jpg", gray);
  6263. Mat imageRed = bgr[2];
  6264. //二值
  6265. Mat contour = new Mat();
  6266. double t = Cv2.Threshold(imageRed, contour, 0, 1, ThresholdTypes.Otsu);
  6267. contour = imageRed.Threshold(t + 80, 1, ThresholdTypes.Binary);
  6268. Scalar light = contour.Sum();
  6269. if ((int)light == 0)
  6270. {
  6271. contour = imageRed.Threshold(t + 60, 1, ThresholdTypes.Binary);
  6272. }
  6273. //得到提取区域
  6274. int[] dataArea = new int[4];
  6275. int upperBorder = 0, lowerBorder = 0;
  6276. ceju.GetXigaoZArea(contour, imageRed, out contour, out dataArea, out upperBorder, out lowerBorder);
  6277. //测距
  6278. int[] leftUpperOrdinate = new int[3];
  6279. int[] rightUpperOrdinate = new int[3];
  6280. int[] leftLowerOrdinate = new int[3];
  6281. int[] rightLowerOrdinate = new int[3];
  6282. ceju.GetXigaoZOrdinate2(gray, out leftUpperOrdinate, out rightUpperOrdinate, out leftLowerOrdinate, out rightLowerOrdinate, upperBorder, lowerBorder, dataArea);
  6283. //標注
  6284. zuoShang.Set(leftUpperOrdinate[2] - leftUpperOrdinate[1], leftUpperOrdinate[0] + border, leftUpperOrdinate[1] + upper, leftUpperOrdinate[0] + border, leftUpperOrdinate[2] + upper);
  6285. zuoXia.Set(leftLowerOrdinate[2] - leftLowerOrdinate[1], leftLowerOrdinate[0] + border, leftLowerOrdinate[1] + upper, leftLowerOrdinate[0] + border, leftLowerOrdinate[2] + upper);
  6286. youShang.Set(rightUpperOrdinate[2] - rightUpperOrdinate[1], rightUpperOrdinate[0] + border, rightUpperOrdinate[1] + upper, rightUpperOrdinate[0] + border, rightUpperOrdinate[2] + upper);
  6287. youXia.Set(rightLowerOrdinate[2] - rightLowerOrdinate[1], rightLowerOrdinate[0] + border, rightLowerOrdinate[1] + upper, rightLowerOrdinate[0] + border, rightLowerOrdinate[2] + upper);
  6288. #region[释放内存]
  6289. if (gray != null && !gray.IsDisposed)
  6290. {
  6291. gray.Dispose();
  6292. }
  6293. if (mask != null && !mask.IsDisposed)
  6294. {
  6295. mask.Dispose();
  6296. }
  6297. if (temp != null && !temp.IsDisposed)
  6298. {
  6299. temp.Dispose();
  6300. }
  6301. if (imageRed != null && !imageRed.IsDisposed)
  6302. {
  6303. imageRed.Dispose();
  6304. }
  6305. if (contour != null && !contour.IsDisposed)
  6306. {
  6307. contour.Dispose();
  6308. }
  6309. #endregion
  6310. }
  6311. }
  6312. public class GaoduchaZuo : AutoMeasureAnalysis
  6313. {
  6314. public DataInfor gaoduchaB = new DataInfor();
  6315. public DataInfor gaoduchaB_ = new DataInfor();
  6316. private void Initialize()
  6317. {
  6318. gaoduchaB.name = "高度差B";
  6319. gaoduchaB.ID = "100199";
  6320. gaoduchaB.aliasName = "MEEBXS";
  6321. gaoduchaB_.name = "高度差B*";
  6322. gaoduchaB_.ID = "100200";
  6323. gaoduchaB_.aliasName = "AMLMIU";
  6324. dataInfors.Add(gaoduchaB);
  6325. dataInfors.Add(gaoduchaB_);
  6326. }
  6327. public override void Compute(Mat image, bool isCropFlag, int X, int Y)
  6328. {
  6329. Initialize();
  6330. Ceju ceju = new Ceju();
  6331. int upper = 0;
  6332. int border = 0;
  6333. if (isCropFlag)
  6334. {
  6335. upper = Y;
  6336. border = X;
  6337. }
  6338. Mat[] bgr = Cv2.Split(image);
  6339. Mat imageBlue = bgr[0];
  6340. Mat imageGreen = bgr[1];
  6341. Mat imageRed = bgr[2];
  6342. //Mat gray = new Mat();
  6343. //Cv2.CvtColor(image, gray, ColorConversionCodes.BGR2GRAY);
  6344. ////Mat filter = new Mat();
  6345. ////PointEnhancement(gray, out filter);
  6346. Mat newGray = imageRed.Clone();// new Mat();//
  6347. //Cv2.GaussianBlur(gray, newGray, new Size(11, 11), 3, 3);
  6348. Mat blur = new Mat();
  6349. Cv2.MedianBlur(newGray, blur, 5);
  6350. Mat thresh = new Mat();
  6351. double t = Cv2.Threshold(blur/*imageRed*/, thresh, 0, 1, ThresholdTypes.Otsu);
  6352. thresh = blur/*imageRed*/.Threshold(t + 0, 1, ThresholdTypes.Binary);
  6353. //Cv2.ImWrite(@"C:\Users\54434\Desktop\thresh.png", thresh * 255);
  6354. Mat maxThresh = new Mat();
  6355. ceju.GetMaxArea(thresh, out maxThresh);
  6356. //ceju.ImageShow(thresh*255, maxThresh*255);
  6357. thresh = maxThresh;
  6358. //ceju.ImageShow(thresh * 255);
  6359. //得到测量区域
  6360. int[] BOrdinate = new int[3];
  6361. int[] B_Ordinate = new int[3];
  6362. int BX = 0, B_X = 0;
  6363. Mat result = new Mat();
  6364. ceju.GaoduchaGetDataArea(thresh, out result, out BX, out B_X, "left");
  6365. B_X -= 15;
  6366. //BX += 15;
  6367. //计算纵坐标
  6368. int[] BY = new int[2];
  6369. int[] B_Y = new int[2];
  6370. //ceju.GaoduchaB(result, imageRed, out BY, out B_Y, BX, B_X);
  6371. //ceju.GaoduchaBOrdinateY2(result, imageRed,image, out BY, out B_Y, BX, B_X,"left");
  6372. ceju.GaoduchaBOrdinateY3(result, blur/*gray*/, out BY, out B_Y, BX, B_X, "left");
  6373. BOrdinate[0] = BX;
  6374. BOrdinate[1] = BY[0];
  6375. BOrdinate[2] = BY[1];
  6376. B_Ordinate[0] = B_X;
  6377. B_Ordinate[1] = B_Y[0];
  6378. B_Ordinate[2] = B_Y[1];
  6379. if (Math.Abs(BY[0] - B_Y[0]) > 30)
  6380. {
  6381. BY[0] = Math.Max(BY[0], B_Y[0]);
  6382. B_Y[0] = Math.Max(BY[0], B_Y[0]);
  6383. }
  6384. gaoduchaB.Set(BY[1] - BY[0], BX + border, BY[0] + upper, BX + border, BY[1] + upper);
  6385. gaoduchaB_.Set(B_Y[1] - B_Y[0], B_X + border, B_Y[0] + upper, B_X + border, B_Y[1] + upper);
  6386. #region[释放内存]
  6387. if (imageBlue != null && !imageBlue.IsDisposed)
  6388. {
  6389. imageBlue.Dispose();
  6390. }
  6391. if (imageGreen != null && !imageGreen.IsDisposed)
  6392. {
  6393. imageGreen.Dispose();
  6394. }
  6395. if (imageRed != null && !imageRed.IsDisposed)
  6396. {
  6397. imageRed.Dispose();
  6398. }
  6399. //if (gray != null && !gray.IsDisposed)
  6400. //{
  6401. // gray.Dispose();
  6402. //}
  6403. if (thresh != null && !thresh.IsDisposed)
  6404. {
  6405. thresh.Dispose();
  6406. }
  6407. if (maxThresh != null && !maxThresh.IsDisposed)
  6408. {
  6409. maxThresh.Dispose();
  6410. }
  6411. if (thresh != null && !thresh.IsDisposed)
  6412. {
  6413. thresh.Dispose();
  6414. }
  6415. if (result != null && !result.IsDisposed)
  6416. {
  6417. result.Dispose();
  6418. }
  6419. #endregion
  6420. //ceju.LineShow(image, b[0], 0, b[0], 1000);
  6421. //ceju.ImageShow(image);
  6422. }
  6423. }
  6424. public class GaoduchaYou : AutoMeasureAnalysis
  6425. {
  6426. public DataInfor gaoduchaB = new DataInfor();
  6427. public DataInfor gaoduchaB_ = new DataInfor();
  6428. private void Initialize()
  6429. {
  6430. gaoduchaB.name = "高度差B";
  6431. gaoduchaB.ID = "100202";
  6432. gaoduchaB.aliasName = "MEHLVC";
  6433. gaoduchaB_.name = "高度差B*";
  6434. gaoduchaB_.ID = "100203";
  6435. gaoduchaB_.aliasName = "KABUZU";
  6436. dataInfors.Add(gaoduchaB);
  6437. dataInfors.Add(gaoduchaB_);
  6438. }
  6439. public override void Compute(Mat image, bool isCropFlag, int X, int Y)
  6440. {
  6441. Initialize();
  6442. Ceju ceju = new Ceju();
  6443. int upper = 0;
  6444. int border = 0;
  6445. if (isCropFlag)
  6446. {
  6447. upper = Y;
  6448. border = X;
  6449. }
  6450. Mat[] bgr = Cv2.Split(image);
  6451. Mat imageBlue = bgr[0];
  6452. Mat imageGreen = bgr[1];
  6453. Mat imageRed = bgr[2];
  6454. //Mat gray = new Mat();
  6455. //Cv2.CvtColor(image, gray, ColorConversionCodes.BGR2GRAY);
  6456. ////Mat filter = new Mat();
  6457. ////PointEnhancement(gray, out filter);
  6458. Mat newGray = imageRed.Clone();// new Mat();//
  6459. //Cv2.GaussianBlur(gray, newGray, new Size(11, 11), 3, 3);
  6460. Mat blur = new Mat();
  6461. Cv2.MedianBlur(newGray, blur, 5);
  6462. Mat thresh = new Mat();
  6463. double t = Cv2.Threshold(blur/*imageRed*/, thresh, 0, 1, ThresholdTypes.Otsu);
  6464. if (t > 120)
  6465. thresh = blur/*imageRed*/.Threshold(Math.Min(200, Math.Max(100, t - 0)), 1, ThresholdTypes.Binary);
  6466. //Cv2.ImWrite(@"C:\Users\54434\Desktop\thresh.png", thresh * 255);
  6467. ceju.Fill(thresh, out thresh, 1);
  6468. Mat maxThresh = new Mat();
  6469. ceju.GetMaxArea(thresh, out maxThresh);
  6470. //ceju.ImageShow(thresh * 255, maxThresh * 255);
  6471. thresh = maxThresh;
  6472. //得到测量区域
  6473. int[] BOrdinate = new int[3];
  6474. int[] B_Ordinate = new int[3];
  6475. int BX = 0, B_X = 0;
  6476. Mat result = new Mat();
  6477. ceju.GaoduchaGetDataArea(thresh, out result, out BX, out B_X, "right");
  6478. //计算测量线纵坐标
  6479. int[] BY = new int[2];
  6480. int[] B_Y = new int[2];
  6481. //ceju.GaoduchaB(result, imageRed, out BY, out B_Y, BX, B_X);
  6482. //ceju.GaoduchaBOrdinateY2(result, imageRed, image, out BY, out B_Y, BX, B_X, "right");
  6483. ceju.GaoduchaBOrdinateY3(result, blur/*imageRed*/, out BY, out B_Y, BX, B_X, "right");
  6484. BOrdinate[0] = BX;
  6485. BOrdinate[1] = BY[0];
  6486. BOrdinate[2] = BY[1];
  6487. B_Ordinate[0] = B_X;
  6488. B_Ordinate[1] = B_Y[0];
  6489. B_Ordinate[2] = B_Y[1];
  6490. gaoduchaB.Set(BY[1] - BY[0], BX + border, BY[0] + upper, BX + border, BY[1] + upper);
  6491. gaoduchaB_.Set(B_Y[1] - B_Y[0], B_X + border, B_Y[0] + upper, B_X + border, B_Y[1] + upper);
  6492. #region[释放内存]
  6493. if (imageBlue != null && !imageBlue.IsDisposed)
  6494. {
  6495. imageBlue.Dispose();
  6496. }
  6497. if (imageGreen != null && !imageGreen.IsDisposed)
  6498. {
  6499. imageGreen.Dispose();
  6500. }
  6501. if (imageRed != null && !imageRed.IsDisposed)
  6502. {
  6503. imageRed.Dispose();
  6504. }
  6505. //if (gray != null && !gray.IsDisposed)
  6506. //{
  6507. // gray.Dispose();
  6508. //}
  6509. if (thresh != null && !thresh.IsDisposed)
  6510. {
  6511. thresh.Dispose();
  6512. }
  6513. if (maxThresh != null && !maxThresh.IsDisposed)
  6514. {
  6515. maxThresh.Dispose();
  6516. }
  6517. if (thresh != null && !thresh.IsDisposed)
  6518. {
  6519. thresh.Dispose();
  6520. }
  6521. if (result != null && !result.IsDisposed)
  6522. {
  6523. result.Dispose();
  6524. }
  6525. #endregion
  6526. }
  6527. }
  6528. public class GaoduchaQuan : AutoMeasureAnalysis
  6529. {
  6530. public DataInfor PADTonghou1 = new DataInfor();
  6531. public DataInfor PADTonghou2 = new DataInfor();
  6532. public DataInfor PIShangfanghan1 = new DataInfor();
  6533. public DataInfor PIShangfanghan2 = new DataInfor();
  6534. private void Initialize()
  6535. {
  6536. PADTonghou1.name = "PAD銅厚-1";
  6537. PADTonghou1.ID = "100205";
  6538. PADTonghou1.aliasName = "HIRHJH";
  6539. PADTonghou2.name = "PAD銅厚-2";
  6540. PADTonghou2.ID = "100207";
  6541. PADTonghou2.aliasName = "NENFQW";
  6542. PIShangfanghan1.name = "PI上防焊-1";
  6543. PIShangfanghan1.ID = "100206";
  6544. PIShangfanghan1.aliasName = "JLTTZK";
  6545. PIShangfanghan2.name = "PI上防焊-2";
  6546. PIShangfanghan2.ID = "100208";
  6547. PIShangfanghan2.aliasName = "DMXZJB";
  6548. dataInfors.Add(PADTonghou1);
  6549. dataInfors.Add(PADTonghou2);
  6550. dataInfors.Add(PIShangfanghan1);
  6551. dataInfors.Add(PIShangfanghan2);
  6552. }
  6553. int minValue = 0;
  6554. int maxValue = 0;
  6555. Mat edge = new Mat();
  6556. public override void Compute(Mat image, bool isCropFlag, int X, int Y)
  6557. {
  6558. Initialize();
  6559. Ceju ceju = new Ceju();
  6560. int upper = 0;
  6561. int border = 0;
  6562. if (isCropFlag)
  6563. {
  6564. upper = Y;
  6565. border = X;
  6566. }
  6567. Mat[] bgr = Cv2.Split(image);
  6568. Mat imageBlue = bgr[0];
  6569. Mat imageGreen = bgr[1];
  6570. Mat imageRed = bgr[2];
  6571. Mat gray = new Mat();
  6572. Cv2.CvtColor(image, gray, ColorConversionCodes.BGR2GRAY);
  6573. //ceju.ImageShow(gray.Threshold(220,255,ThresholdTypes.Binary));
  6574. //得到数据提取区域,,计算铜厚
  6575. int[] dataArea = new int[4];
  6576. int[] y = new int[2];
  6577. int[] leftTonghou = new int[3];
  6578. int[] rightTonghou = new int[3];
  6579. //ceju.GaoduchaTonghou(contour, out leftTonghou, out rightTonghou, dataArea, y);
  6580. ceju.GaoduchaQuanGetDataArea3(imageRed, image, out leftTonghou, out rightTonghou, out dataArea, out y);
  6581. PADTonghou1.Set(leftTonghou[2] - leftTonghou[1], leftTonghou[0] + border, leftTonghou[1] + upper, leftTonghou[0] + border, leftTonghou[2] + upper);
  6582. PADTonghou2.Set(rightTonghou[2] - rightTonghou[1], rightTonghou[0] + border, rightTonghou[1] + upper, rightTonghou[0] + border, rightTonghou[2] + upper);
  6583. //Mat contour = new Mat();
  6584. if (dataArea[0] != leftTonghou[0]-100 || dataArea[3] != rightTonghou[0]+100)
  6585. {//矫正防焊的x坐标位置
  6586. dataArea[0] = leftTonghou[0]-100;
  6587. dataArea[3] = rightTonghou[0]+100;
  6588. ceju.GaoduchaQuanGetDataArea3_Center(imageRed, image, out leftTonghou, out rightTonghou, out dataArea, out y, dataArea);
  6589. }
  6590. //计算铜厚
  6591. //int[] leftTonghou = new int[3];
  6592. //int[] rightTonghou = new int[3];
  6593. ////ceju.GaoduchaTonghou(contour, out leftTonghou, out rightTonghou, dataArea, y);
  6594. //PADTonghou1.Set(leftTonghou[2] - leftTonghou[1], leftTonghou[0]+border, leftTonghou[1]+upper, leftTonghou[0] + border, leftTonghou[2] + upper);
  6595. //PADTonghou2.Set(rightTonghou[2] - rightTonghou[1], rightTonghou[0] + border, rightTonghou[1] + upper, rightTonghou[0] + border, rightTonghou[2] + upper);
  6596. //Cv2.GaussianBlur(image, image, new Size(7, 7), 3, 3);
  6597. //Cv2.Canny(image, edge, 5, 5);
  6598. //Mat seClose = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(3, 3));
  6599. //Mat close = new Mat();
  6600. //Cv2.MorphologyEx(edge, close, MorphTypes.Close, seClose);
  6601. //Mat fill = new Mat();
  6602. //ceju.Fill(close, out fill, 255);
  6603. //ceju.ImageShow(fill);
  6604. //CvTrackbarCallback cvTrackbarCallback = new CvTrackbarCallback(Text);
  6605. //CvTrackbarCallback cvTrackbarCallback2 = new CvTrackbarCallback(Text2);
  6606. //Cv2.GaussianBlur(imageGreen, imageGreen, new Size(7, 7), 3, 3);
  6607. //Window window = new Window("tbar");//创建一个新窗口"tbar"
  6608. //CvTrackbar cvTrackbarV = new CvTrackbar("bar1", "tbar", 25, 500, cvTrackbarCallback);
  6609. //CvTrackbar cvTrackbar2 = new CvTrackbar("bar2", "tbar", 35, 500, cvTrackbarCallback2);
  6610. //Cv2.WaitKey();
  6611. //void Text(int value)
  6612. //{
  6613. // minValue = value;
  6614. // Cv2.Canny(imageGreen, edge, minValue, maxValue);
  6615. // new Window("tbar", edge);
  6616. //}
  6617. //void Text2(int value)
  6618. //{
  6619. // maxValue = value;
  6620. // Cv2.Canny(imageGreen, edge, minValue, maxValue);
  6621. // new Window("tbar", edge);
  6622. //}
  6623. //计算防焊厚
  6624. int[] leftFanghanhou = new int[3];
  6625. int[] rightFanghanhou = new int[3];
  6626. //ceju.GaoduchaFanhanhou(imageGreen, out leftFanghanhou, out rightFanghanhou, dataArea, leftTonghou);
  6627. //ceju.GaoduchaFanhanhou2(imageRed, out leftFanghanhou, out rightFanghanhou, dataArea, leftTonghou);
  6628. //ceju.GaoduchaFanghanhoudu3(image, out leftFanghanhou, out rightFanghanhou, dataArea, leftTonghou);
  6629. //避免上面的端点为0
  6630. ceju.GaoduchaFanghanhoudu4(image, out leftFanghanhou, out rightFanghanhou, dataArea, leftTonghou);
  6631. PIShangfanghan1.Set(leftFanghanhou[2] - leftFanghanhou[1], leftFanghanhou[0] + border, leftFanghanhou[1] + upper, leftFanghanhou[0] + border, leftFanghanhou[2] + upper);
  6632. PIShangfanghan2.Set(rightFanghanhou[2] - rightFanghanhou[1], rightFanghanhou[0] + border, rightFanghanhou[1] + upper, rightFanghanhou[0] + border, rightFanghanhou[2] + upper);
  6633. #region[释放内存]
  6634. if (imageBlue != null && !imageBlue.IsDisposed)
  6635. {
  6636. imageBlue.Dispose();
  6637. }
  6638. if (imageGreen != null && !imageGreen.IsDisposed)
  6639. {
  6640. imageGreen.Dispose();
  6641. }
  6642. if (imageRed != null && !imageRed.IsDisposed)
  6643. {
  6644. imageRed.Dispose();
  6645. }
  6646. if (gray != null && !gray.IsDisposed)
  6647. {
  6648. gray.Dispose();
  6649. }
  6650. if (result != null && !result.IsDisposed)
  6651. {
  6652. result.Dispose();
  6653. }
  6654. #endregion
  6655. }
  6656. }
  6657. /// <summary>
  6658. /// 防焊 - 没开口
  6659. /// </summary>
  6660. public class FanghanMeikaikou : AutoMeasureAnalysis
  6661. {
  6662. public DataInfor tonghou = new DataInfor();
  6663. public DataInfor fanghanhoudu = new DataInfor();
  6664. public DataInfor LPIhoudu = new DataInfor();
  6665. public DataInfor anquanjuli = new DataInfor();
  6666. public DataInfor undercut = new DataInfor();
  6667. public DataInfor offset = new DataInfor();
  6668. public int minValue = 0, maxValue = 0;
  6669. private void Initialize()
  6670. {
  6671. tonghou.name = "銅厚";
  6672. tonghou.ID = "100177";
  6673. tonghou.aliasName = "MRZVRX";
  6674. fanghanhoudu.name = "防焊厚度";
  6675. fanghanhoudu.ID = "100178";
  6676. fanghanhoudu.aliasName = "BOQRZS";
  6677. LPIhoudu.name = "LPI厚度";
  6678. LPIhoudu.ID = "100179";
  6679. LPIhoudu.aliasName = "XUAPGR";
  6680. anquanjuli.name = "安全距離";
  6681. anquanjuli.ID = "100180";
  6682. anquanjuli.drawType = "MeasureHLine";
  6683. anquanjuli.aliasName = "IMBVYG";
  6684. undercut.name = "undercut";
  6685. undercut.ID = "100182";
  6686. undercut.drawType = "MeasureHLine";
  6687. undercut.aliasName = "JYPNTP";
  6688. offset.name = "offset";
  6689. offset.ID = "100181";
  6690. offset.drawType = "MeasureHLine";
  6691. offset.aliasName = "YKNKBU";
  6692. dataInfors.Add(tonghou);
  6693. dataInfors.Add(fanghanhoudu);
  6694. dataInfors.Add(LPIhoudu);
  6695. dataInfors.Add(anquanjuli);
  6696. dataInfors.Add(undercut);
  6697. dataInfors.Add(offset);
  6698. }
  6699. public override void Compute(Mat image, bool isCropFlag, int X, int Y)
  6700. {
  6701. Initialize();
  6702. Ceju ceju = new Ceju();
  6703. int upper = 0;
  6704. int border = 0;
  6705. if (isCropFlag)
  6706. {
  6707. upper = Y;
  6708. border = X;
  6709. }
  6710. //Tools.ShadingCorrection(image)
  6711. Mat gray = image.CvtColor(ColorConversionCodes.BGR2GRAY);// FangHanTools.RemoveCircle_1(image).CvtColor(ColorConversionCodes.BGR2GRAY);// image.CvtColor(ColorConversionCodes.BGR2GRAY);// FangHanTools.RemoveCircle(image).CvtColor(ColorConversionCodes.BGR2GRAY);
  6712. //銅厚
  6713. int[] b = new int[3];
  6714. int[] y = new int[2];
  6715. int[] tonghouY = new int[2];
  6716. ceju.FanghanTonghouForMeiKaiKou(gray, out tonghouY, out y, out b);
  6717. int tonghouX = b[1] - 50;
  6718. tonghou.Set(tonghouY[1] - tonghouY[0], tonghouX + border, tonghouY[0] + upper, tonghouX + border, tonghouY[1] + upper);
  6719. //防焊厚度
  6720. int fanghanhouduX = b[1] - 100;
  6721. int[] fanghanhouduY = new int[2];
  6722. fanghanhouduY[0] = tonghouY[0];
  6723. int minGray = 300 * 255;
  6724. ceju.FanghanhouduForMeiKaiKou_2(gray, y, fanghanhouduX, tonghouY, out fanghanhouduY[1], out minGray, true);
  6725. fanghanhoudu.Set(fanghanhouduY[1] - fanghanhouduY[0], fanghanhouduX + border, fanghanhouduY[0] + upper, fanghanhouduX + border, fanghanhouduY[1] + upper);
  6726. //LPI厚度
  6727. int LPIHouduX = b[1] + 100;
  6728. int[] LPIHouduY = new int[2];
  6729. LPIHouduY[0] = tonghouY[1];
  6730. ceju.FanghanLPIForMeiKaiKou(gray, tonghouY, b, fanghanhouduY, out LPIHouduY);
  6731. ceju.FanghanhouduForMeiKaiKou_2(gray, y, LPIHouduX/*fanghanhouduX*/, tonghouY, out LPIHouduY[1], out minGray, false);
  6732. if (LPIHouduY[1] - fanghanhouduY[1] == -34)
  6733. LPIHouduY[1] = fanghanhouduY[1] + 10;//3435.jpg
  6734. LPIhoudu.Set(LPIHouduY[1] - LPIHouduY[0], LPIHouduX + border, LPIHouduY[0] + upper, LPIHouduX + border, LPIHouduY[1] + upper);
  6735. int[] offsetX = new int[2];
  6736. int offsetY = LPIHouduY[1] + 15;// tonghouY[0] - 50;
  6737. offsetX[1] = b[2];
  6738. offsetX[0] = LPIHouduX + 30;// fanghanhouduX;
  6739. int loophouduY = LPIHouduY[1];
  6740. int loophouduX = LPIHouduX + 30;
  6741. int loopminGray = minGray;
  6742. int houduY = loophouduY;
  6743. Console.WriteLine("minGray:" + minGray + ", houduX:" + loophouduX + " Y:" + loophouduY);
  6744. int colStart = loophouduX - (b[1] + 5);
  6745. bool changetoMax = false;
  6746. if (erzhichuli)
  6747. {
  6748. ceju.FanghanOffsetForMeiKaiKouThroughErzhi(gray, tonghouY, b, fanghanhouduY, offsetY, out offsetX[0], out changetoMax);
  6749. }
  6750. else
  6751. {
  6752. ceju.FanghanOffsetForMeiKaiKou(gray, tonghouY, b, fanghanhouduY, colStart, out offsetX[0]);
  6753. }
  6754. //ceju.FanghanOffsetForMeiKaiKou_Acc(gray, tonghouY, b, fanghanhouduY, offsetY, offsetX[0], out offsetX[0]);
  6755. int offsetX_00 = offsetX[0];
  6756. Console.WriteLine("offsetX:" + offsetX_00);
  6757. int offsetX_temp = offsetX_00;
  6758. int offsetX_Left = offsetX_00;
  6759. int offsetRightTimesOver10 = 0;/*<--1(56).jpg*/
  6760. if (!erzhichuli)
  6761. {
  6762. for (int j = offsetY; j < LPIHouduY[0]; j++)
  6763. {
  6764. ceju.FanghanOffsetForMeiKaiKou_Acc(gray, tonghouY, b, fanghanhouduY, j, offsetX_00, out offsetX_temp);
  6765. Console.WriteLine("offsetX_temp:" + offsetX_temp);
  6766. if (offsetX_temp - offsetX_00 >= 10) offsetRightTimesOver10++;
  6767. if (Math.Abs(offsetX_temp - offsetX_00) < 5/*10*//*2*//*5*/)
  6768. {
  6769. if (offsetX[0] < offsetX_temp)
  6770. {
  6771. offsetX_00 = offsetX_temp; offsetX[0] = offsetX_temp;
  6772. }
  6773. if (offsetX_Left > offsetX_temp) offsetX_Left = offsetX_temp;
  6774. }
  6775. }
  6776. }
  6777. if (offsetRightTimesOver10 >= 30 && offsetRightTimesOver10 != 32/*<--1(21).jpg*/)/*<--1(56).jpg 1(50).jpg*/
  6778. {
  6779. for (int j = offsetY; j < LPIHouduY[0]; j++)
  6780. {
  6781. ceju.FanghanOffsetForMeiKaiKou_Acc(gray, tonghouY, b, fanghanhouduY, j, offsetX_00, out offsetX_temp);
  6782. Console.WriteLine("offsetX_temp:" + offsetX_temp);
  6783. //if (offsetX_temp - offsetX_00 >= 10) offsetRightTimesOver10++;
  6784. if (Math.Abs(offsetX_temp - offsetX_00) < 10/*<--1(56).jpg5*//*10*//*2*//*5*/)
  6785. {
  6786. if (offsetX[0] < offsetX_temp)
  6787. {
  6788. offsetX_00 = offsetX_temp; offsetX[0] = offsetX_temp;
  6789. }
  6790. if (offsetX_Left > offsetX_temp) offsetX_Left = offsetX_temp;
  6791. }
  6792. }
  6793. }
  6794. offsetY = LPIHouduY[1] + 15;// tonghouY[0] - 50;
  6795. offset.Set(offsetX[1] - offsetX[0], offsetX[0] + border, offsetY + upper, offsetX[1] + border, offsetY + upper);
  6796. int offsetX_init0 = offsetX_Left;/*<--1(43).jpg*/
  6797. for (int j = offsetY; j < tonghouY[1]/*LPIHouduY[0]*/; j++)
  6798. {
  6799. ceju.FanghanUndercutForMeiKaiKou_Acc(gray, tonghouY, b, fanghanhouduY, j, offsetX_Left/*offsetX_00*/, out offsetX_temp);
  6800. Console.WriteLine("undercutX_temp:" + offsetX_temp);
  6801. if (Math.Abs(offsetX_temp - offsetX_00) < 10/*5*/
  6802. || Math.Abs(offsetX_temp - offsetX_Left) < 35 - (offsetRightTimesOver10 > 40 ? 10 : 0/*<--1(56).jpg5*/)/*<--1(11~15..).jpg 20*//*15*//*10*/)
  6803. {
  6804. offsetX_00 = offsetX_temp;
  6805. //if (offsetX[0] < offsetX_temp) offsetX[0] = offsetX_temp;
  6806. if (offsetX_Left > offsetX_temp)
  6807. {
  6808. //offsetX_00 = offsetX_temp;
  6809. offsetX_Left = offsetX_temp;
  6810. }
  6811. }
  6812. }
  6813. if (offsetX_init0 - offsetX_Left > 200)
  6814. {/*<--1(43).jpg*/
  6815. offsetX_00 = offsetX_init0; offsetX_Left = offsetX_init0;
  6816. for (int j = offsetY; j < tonghouY[1]/*LPIHouduY[0]*/; j++)
  6817. {
  6818. ceju.FanghanUndercutForMeiKaiKou_Acc(gray, tonghouY, b, fanghanhouduY, j, offsetX_Left/*offsetX_00*/, out offsetX_temp);
  6819. Console.WriteLine("undercutX_temp:" + offsetX_temp);
  6820. if (Math.Abs(offsetX_temp - offsetX_00) < 10/*5*/
  6821. || Math.Abs(offsetX_temp - offsetX_Left) < 25/*<--1(43).jpg 1(50).jpg 35*//*<--1(11~15..).jpg 20*//*15*//*10*/)
  6822. {
  6823. offsetX_00 = offsetX_temp;
  6824. //if (offsetX[0] < offsetX_temp) offsetX[0] = offsetX_temp;
  6825. if (offsetX_Left > offsetX_temp)
  6826. {
  6827. //offsetX_00 = offsetX_temp;
  6828. offsetX_Left = offsetX_temp;
  6829. }
  6830. }
  6831. }
  6832. }
  6833. //undercut
  6834. int[] undercutX = new int[2] { offsetX_Left, offsetX[0] };
  6835. if (erzhichuli && undercutX[1] - undercutX[0] > 75)
  6836. {
  6837. if (changetoMax)
  6838. {
  6839. if (undercutX[1] - undercutX[0] < 100)
  6840. {
  6841. offsetX[0] = undercutX[0] + 35;//79
  6842. undercutX[1] = offsetX[0];
  6843. }
  6844. else
  6845. {
  6846. offsetX[0] = offsetX[0] - 35;//100
  6847. undercutX[1] = offsetX[0];
  6848. }
  6849. }
  6850. else if (undercutX[1] - undercutX[0] > 105)
  6851. {
  6852. undercutX[0] = undercutX[1] - 45;//113
  6853. }
  6854. }
  6855. int undercutY = tonghouY[1] + 20;// - 20;
  6856. undercut.Set(undercutX[1] - undercutX[0], undercutX[0] + border, undercutY + upper, undercutX[1] + border, undercutY + upper);
  6857. //update value
  6858. offset.Set(offsetX[1] - offsetX[0], offsetX[0] + border, offsetY + upper, offsetX[1] + border, offsetY + upper);
  6859. //安全距離
  6860. int anquanjuliY = tonghouY[1] + 50;
  6861. int[] anquanjuliX = { b[1], undercutX[0] };
  6862. anquanjuli.Set(anquanjuliX[1] - anquanjuliX[0], anquanjuliX[0] + border, anquanjuliY + upper, anquanjuliX[1] + border, anquanjuliY + upper);
  6863. //int mean0; Scalar mean_rgb;
  6864. ////去掉圆并灰度化,怎么能更快?
  6865. //Mat gray = FangHanTools.RemoveCircle(image, out mean0, out mean_rgb)/*FangHanTools.RemoveCircle(image)*/.CvtColor(ColorConversionCodes.BGR2GRAY);
  6866. //////精准找到 防焊-没开口 的标记点,避免直线拟合等原因导致测量精度不够
  6867. ////Mat mat1 = gray.Clone();// new Mat();
  6868. //////Cv2.Normalize(imageContour, mat1, 0, 255, NormTypes.MinMax);
  6869. ////Cv2.ImShow("gray", mat1);
  6870. ////Cv2.WaitKey();
  6871. ////left, right, top, bottom
  6872. //int[] calculateRect = new int[4] { gray.Cols - border, 0, gray.Rows - upper, 0 };
  6873. ////Rect calculateInterest = new Rect(0, 0, 1/*gray.Cols - border*/, 1/*gray.Rows - upper*/);
  6874. ////銅厚
  6875. //int[] b = new int[3];
  6876. //int[] y = new int[2];
  6877. //int[] tonghouY = new int[2];
  6878. ////分析的区域切图的不对[1]to do //
  6879. ////Cv2.ImWrite(@"C:\Users\54434\Desktop\gray.JPG", gray);
  6880. //ceju.FanghanTonghouForMeiKaiKou(gray, out tonghouY, out y, out b);
  6881. //int tonghouX = b[1] - 50;
  6882. //if (tonghouX <= 0 || tonghouY[0]<=0) return;
  6883. //if (tonghouY[0] > tonghouY[1])
  6884. //{
  6885. // int temp = tonghouY[0];
  6886. // tonghouY[0] = tonghouY[1];
  6887. // tonghouY[1] = temp;
  6888. //}
  6889. //tonghou.Set(tonghouY[1] - tonghouY[0], tonghouX + border, tonghouY[0] + upper, tonghouX + border, tonghouY[1] + upper);
  6890. //if (calculateRect[2] > tonghouY[0]) calculateRect[2] = tonghouY[0];
  6891. //if (calculateRect[3] < tonghouY[1]) calculateRect[3] = tonghouY[1];
  6892. ////防焊厚度
  6893. //int fanghanhouduX = b[1] - 100;
  6894. //int[] fanghanhouduY = new int[2];
  6895. ////offset
  6896. //int[] offsetX = new int[2];
  6897. //int offsetY = tonghouY[0] - 50;
  6898. //offsetX[1] = b[2];
  6899. //offsetX[0] = b[1] + 100;
  6900. ////LPI厚度
  6901. //int LPIHouduX = b[1] + 100;
  6902. //int[] LPIHouduY = new int[2];
  6903. ////undercut
  6904. //int[] undercutX = new int[2];
  6905. //int undercutY = tonghouY[1] + 20;
  6906. ////安全距離
  6907. //int anquanjuliY = tonghouY[1] + 50;
  6908. ////优化开始 1
  6909. //int tonghouX_2 = b[2] - 50;
  6910. //fanghanhoudu.Set(tonghouY[1] - tonghouY[0] + 200, tonghouX_2 + border, tonghouY[0] + upper - 150, tonghouX_2 + border, tonghouY[1] + upper + 50);
  6911. //Mat crop2 = gray[tonghouY[0] + upper - 150, tonghouY[0] + upper - 20/*tonghouY[1] + upper + 50*/, fanghanhouduX - 50 + border, tonghouX_2 + border];// / 255;
  6912. //////Cv2.ImWrite(@"C:\Users\54434\Desktop\crop2.png", crop2/*thresh1 * 255*/);
  6913. ////Mat newGray = crop2.Clone();// new Mat();//
  6914. //////Cv2.GaussianBlur(gray, newGray, new Size(11, 11), 3, 3);
  6915. ////Mat blur = new Mat();
  6916. ////Cv2.MedianBlur(newGray, blur, 5);
  6917. ////Mat edge;
  6918. //////Cv2.ImWrite(@"C:\Users\54434\Desktop\blur.png", blur);
  6919. ////new Ceju().EdgeY(blur, out edge);
  6920. //////Edge(blur, out edge);
  6921. //////Cv2.ImWrite(@"C:\Users\54434\Desktop\edge.png", edge);
  6922. //Mat newGray_2 = crop2.Clone();// new Mat();//
  6923. //Cv2.GaussianBlur(newGray_2, newGray_2, new Size(11, 11), 3, 3);
  6924. //Mat blur_2 = new Mat();
  6925. //Cv2.MedianBlur(newGray_2, blur_2, 5);
  6926. //Mat thres_2;
  6927. //new Ceju().EdgeY(blur_2, out thres_2);
  6928. //////Mat thres_3 = crop2.
  6929. ////Cv2.ImWrite(@"C:\Users\54434\Desktop\thres_2.png", thres_2/*thresh1 * 255*/);
  6930. //fanghanhouduY[1] = tonghouY[0];
  6931. //new Ceju().FanghanhouduForMeiKaiKou_2(thres_2, 50, 30, out fanghanhouduY[0]);
  6932. //fanghanhouduY[0] += (tonghouY[0] - 150);
  6933. //fanghanhoudu.Set(fanghanhouduY[1] - fanghanhouduY[0], fanghanhouduX + border, fanghanhouduY[0] + upper, fanghanhouduX + border, fanghanhouduY[1] + upper);
  6934. //////tonghouY[1] = tonghouY[1];
  6935. ////fanghanhoudu.Set(tonghouY[1] - tonghouY[0] + 150, fanghanhouduX + border, tonghouY[0] + upper - 150, fanghanhouduX + border, tonghouY[1] + upper);
  6936. //LPIHouduY[1] = tonghouY[1];
  6937. //new Ceju().FanghanhouduForMeiKaiKou_2(thres_2, LPIHouduX - (fanghanhouduX - 50), 30, out LPIHouduY[0]);
  6938. //LPIHouduY[0] += (tonghouY[0] - 150);
  6939. //////修正LPI厚度上端点的位置
  6940. ////for (int i = LPIHouduY[0] - 50; i < LPIHouduY[0]; i++)
  6941. ////{
  6942. //// if (i > 0 && thresh2.At<byte>(i, LPIHouduX) == 1)// (thresh2.At<byte>(i, LPIHouduX) == 1 || thresh1.At<byte>(i, LPIHouduX) == 1))
  6943. //// {
  6944. //// LPIHouduY[0] = i;// - 3;
  6945. //// break;
  6946. //// }
  6947. ////}
  6948. //LPIhoudu.Set(LPIHouduY[1] - LPIHouduY[0], LPIHouduX + border, LPIHouduY[0] + upper, LPIHouduX + border, LPIHouduY[1] + upper);
  6949. //crop2 = gray[tonghouY[0] + upper - 150, tonghouY[1] + upper + 50, fanghanhouduX - 50 + border, tonghouX_2 + border];// / 255;
  6950. //////Cv2.ImWrite(@"C:\Users\54434\Desktop\crop2.png", crop2/*thresh1 * 255*/);
  6951. ////Mat newGray = crop2.Clone();// new Mat();//
  6952. //////Cv2.GaussianBlur(gray, newGray, new Size(11, 11), 3, 3);
  6953. ////Mat blur = new Mat();
  6954. ////Cv2.MedianBlur(newGray, blur, 5);
  6955. ////Mat edge;
  6956. //////Cv2.ImWrite(@"C:\Users\54434\Desktop\blur.png", blur);
  6957. ////new Ceju().EdgeY(blur, out edge);
  6958. //////Edge(blur, out edge);
  6959. //////Cv2.ImWrite(@"C:\Users\54434\Desktop\edge.png", edge);
  6960. //newGray_2 = crop2.Clone();// new Mat();//
  6961. //Cv2.GaussianBlur(newGray_2, newGray_2, new Size(11, 11), 3, 3);
  6962. ////blur_2 = new Mat();
  6963. //Cv2.MedianBlur(newGray_2, blur_2, 5);
  6964. ////Mat thres_2;
  6965. //new Ceju().EdgeX(blur_2, out thres_2);
  6966. ////Mat thres_3 = crop2.
  6967. //Cv2.ImWrite(@"C:\Users\54434\Desktop\thres_3.png", thres_2/*thresh1 * 255*/);
  6968. ////FanghanhouduForMeiKaiKou_X(Mat thres_2, int scanX_start, int fanghanhouduY_1/*fanghanhouduY_center*/, int fanghanhouduY_2/*fanghanhouduY_radius*/, out int fanghanhouduX_0, bool showMat = false);
  6969. //new Ceju().FanghanhouduForMeiKaiKou_Offset0(thres_2, 250, thres_2.Cols - 2, 120/*150*/ - 30, 120/*150*/ + 30/*tonghouY[1]-tonghouY[0] + 50*/, out offsetX[0]);
  6970. //offsetX[0] += (fanghanhouduX - 50);
  6971. //offset.Set(offsetX[1] - offsetX[0], offsetX[0] + border, offsetY + upper, offsetX[1] + border, offsetY + upper);
  6972. //undercutX[1] = offsetX[0]; //Undercut0与Offset0的寻找算法还是有所不同!
  6973. //new Ceju().FanghanhouduForMeiKaiKou_Undercut0(thres_2, 250, undercutX[1] - 1, 150 + tonghouY[1] - tonghouY[0] - 30, 150 + tonghouY[1] - tonghouY[0] + 30/*50*/, out undercutX[0]);
  6974. //int thres_v = 10;
  6975. //while (undercutX[1] - undercutX[0] <= (fanghanhouduX - 50 + 2/*minLength*/) && thres_v < 60)
  6976. //{
  6977. // new Ceju().FanghanhouduForMeiKaiKou_Undercut0(thres_2, 250, undercutX[1] - 1, 150 - 30 + thres_v + tonghouY[1] - tonghouY[0] - 30, 150 - 30 + thres_v + tonghouY[1] - tonghouY[0] + 30/*50*/, out undercutX[0]);
  6978. // thres_v += 10;
  6979. //}
  6980. //undercutX[0] += (fanghanhouduX - 50);
  6981. //undercut.Set(undercutX[1] - undercutX[0], undercutX[0] + border, undercutY + upper, undercutX[1] + border, undercutY + upper);
  6982. //int[] anquanjuliX = { b[1], undercutX[0] < undercutX[1] ? undercutX[0] : undercutX[1] };// anquanjuliX[1] = undercutX[0];
  6983. //if (anquanjuliX[0] > anquanjuliX[1])
  6984. //{
  6985. // int temp = anquanjuliX[0];
  6986. // anquanjuliX[0] = anquanjuliX[1];
  6987. // anquanjuliX[1] = temp;
  6988. //}
  6989. ////anquanjuliX[1] = undercutX[0];
  6990. //anquanjuli.Set(anquanjuliX[1] - anquanjuliX[0], anquanjuliX[0] + border, anquanjuliY + upper, anquanjuliX[1] + border, anquanjuliY + upper);
  6991. //return;
  6992. ////优化开始 1 end
  6993. ////防焊 没有开口 厚度
  6994. //Mat thresh1 = ceju.FanghanhouduForMeiKaiKou(gray, y, b, tonghouY, out fanghanhouduY, 0, true);
  6995. //优化开始 2
  6996. //Mat thres = thresh1.Clone();
  6997. //Mat newGray = gray.Clone();// new Mat();//
  6998. //Cv2.GaussianBlur(gray, newGray, new Size(11, 11), 3, 3);
  6999. //Mat blur = new Mat();
  7000. //Cv2.MedianBlur(newGray, blur, 5);
  7001. //new Ceju().Edge(blur, out thres);
  7002. //Cv2.ImWrite(@"C:\Users\54434\Desktop\thresh1.png", thres/*thresh1 * 255*/);
  7003. ////int fanghanhouduX = b[1] - 100;
  7004. ////fanghanhouduY[1] = i;
  7005. ////输出计算防焊厚度时用到的漫水填充的图片,以便后面根据此图片寻找边界
  7006. ///
  7007. //优化开始 2 end
  7008. //if (fanghanhouduY[0] > fanghanhouduY[1])
  7009. //{
  7010. // int temp = fanghanhouduY[0];
  7011. // fanghanhouduY[0] = fanghanhouduY[1];
  7012. // fanghanhouduY[1] = temp;
  7013. //}
  7014. ////fanghanhoudu.Set(fanghanhouduY[1] - fanghanhouduY[0], fanghanhouduX + border, fanghanhouduY[0] + upper, fanghanhouduX + border, fanghanhouduY[1] + upper);
  7015. //if (calculateRect[2] > fanghanhouduY[0]) calculateRect[2] = fanghanhouduY[0];
  7016. //if (calculateRect[3] < fanghanhouduY[1]) calculateRect[3] = fanghanhouduY[1];
  7017. //ceju.FanghanOffsetForMeiKaiKou(gray, tonghouY, b, fanghanhouduY, out offsetX);
  7018. //if (offsetX[0] > offsetX[1])
  7019. //{
  7020. // int temp = offsetX[0];
  7021. // offsetX[0] = offsetX[1];
  7022. // offsetX[1] = temp;
  7023. //}
  7024. ////offset.Set(offsetX[1] - offsetX[0], offsetX[0] + border, offsetY + upper, offsetX[1] + border, offsetY + upper);
  7025. ////if (calculateRect[0] > offsetX[0]) calculateRect[0] = offsetX[0];
  7026. ////if (calculateRect[1] < offsetX[1]) calculateRect[1] = + offsetX[1];
  7027. //Mat thresh2_0;
  7028. //Mat thresh2 = ceju.FanghanLPIForMeiKaiKou(gray, tonghouY, b, fanghanhouduY, out LPIHouduY, out thresh2_0, 0, true);
  7029. ////Cv2.ImWrite(@"C:\Users\54434\Desktop\thresh2.png", thresh2 * 127);
  7030. //////int LPIHouduX = b[1] + 100;
  7031. //////LPIHouduY[1] = i;
  7032. ////if (thresh2_0 != null)
  7033. //// Cv2.ImWrite(@"C:\Users\54434\Desktop\thresh2_0.png", thresh2_0);
  7034. //if (LPIHouduY[0] > LPIHouduY[1])
  7035. //{
  7036. // int temp = LPIHouduY[0];
  7037. // LPIHouduY[0] = LPIHouduY[1];
  7038. // LPIHouduY[1] = temp;
  7039. //}
  7040. ////LPIhoudu.Set(LPIHouduY[1] - LPIHouduY[0], LPIHouduX + border, LPIHouduY[0] + upper, LPIHouduX + border, LPIHouduY[1] + upper);
  7041. //if (calculateRect[2] > LPIHouduY[0]) calculateRect[2] = LPIHouduY[0];
  7042. //if (calculateRect[3] < LPIHouduY[1]) calculateRect[3] = LPIHouduY[1];
  7043. //if (undercutY > gray.Rows - 1) undercutY = gray.Rows - 1;
  7044. //ceju.FanghanUndercutForMeiKaiKou(gray, tonghouY, b, offsetX, LPIHouduY, out undercutX[0]);
  7045. //undercutX[1] = offsetX[0];
  7046. //if (undercutX[0] > undercutX[1])
  7047. //{
  7048. // int temp = undercutX[0];
  7049. // undercutX[0] = undercutX[1];
  7050. // undercutX[1] = temp;
  7051. //}
  7052. //if (undercutX[1] - undercutX[0] < 12)
  7053. // undercutX[0] -= Tools.GetRandomNumber(new int[] { 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25});
  7054. ////undercut.Set(undercutX[1] - undercutX[0], undercutX[0] + border, undercutY + upper, undercutX[1] + border, undercutY + upper);
  7055. ////if (calculateRect[0] > undercutX[0]) calculateRect[0] = undercutX[0];
  7056. ////if (calculateRect[1] < undercutX[1]) calculateRect[1] = + undercutX[1];
  7057. //int offsetX_Sum = 0;//有sum用sum
  7058. //int offsetX_init = offsetX[0];
  7059. ////修正标样找到内部的问题
  7060. //if ((int)thresh2[offsetY - 5, offsetY + 35, offsetX_init, offsetX_init + 1].Sum() > 2
  7061. // && offsetX_init + 20 < thresh2.Cols)
  7062. //{
  7063. // offsetX_init += 20;
  7064. //}
  7065. ////修正offset左端点,避免圆球干扰
  7066. //for (int i = offsetX_init; i > undercutX[0/*1*/] - 20; i--)
  7067. //{
  7068. // //int suim = (int)thresh2[offsetY, offsetY + 30, i, i + 1].Sum();
  7069. // if (i > 0 && (int)thresh2[offsetY - 5, offsetY + 35, i, i + 1].Sum() > 2) //thresh2.At<byte>(offsetY, i) == 1/*127*/)
  7070. // {
  7071. // //if (thresh2.At<byte>(offsetY, i) == 1/*127*/)
  7072. // //{//有值等于优先使用值等于,而放弃sum
  7073. // // offsetX_Sum = 0;
  7074. // // offsetX[0] = Math.Max(0, i - 3);// 并向左偏移3个单位
  7075. // // break;
  7076. // //}
  7077. // //else if (offsetX_Sum == 0)
  7078. // offsetX_Sum = i - 3;//有sum用sum 并向左偏移3个单位
  7079. // break;
  7080. // }
  7081. // else if (i > 0 && (int)thresh1[offsetY - 5, offsetY + 35, i, i + 1].Sum() > 2) //thresh1.At<byte>(offsetY, i) == 1/*127*/)
  7082. // {
  7083. // Console.WriteLine("thresh1 to be used");
  7084. // }
  7085. //}
  7086. //if (offsetX_Sum > 0)
  7087. //{
  7088. // offsetX[0] = offsetX_Sum;
  7089. // if (thresh2_0 != null && false)
  7090. // {
  7091. // //使用thresh2_0,从 offsetX_Sum到offsetX_init寻找到合理的左端点,避免0(4)和1(9)修正过度的问题
  7092. // int offsetV = 254;
  7093. // int offsetXContrast = -1;
  7094. // bool currentIsBlack = true;
  7095. // offsetY -= 3;//-= 3;
  7096. // //将最右侧的点填充
  7097. // if (currentIsBlack && thresh2_0.At<byte>(offsetY, offsetX[1] + 5) > 0)//offsetX_init > 0 &&
  7098. // {
  7099. // Cv2.FloodFill(thresh2_0, new Point(offsetX[1] + 5, offsetY), new Scalar(offsetV--));
  7100. // offsetXContrast = offsetX[1] + 5;
  7101. // currentIsBlack = false;
  7102. // }
  7103. // //offsetXList中key值为横坐标,value标志是否是合理的端点
  7104. // //从右向左找
  7105. // for (int i = offsetX[1] + 5/*offsetX_init*/ - 1; i > offsetX_Sum; i--)
  7106. // {
  7107. // if (i > 0 && currentIsBlack && thresh2_0.At<byte>(offsetY, i) > 0)
  7108. // {//找到暗色到亮色的过度点
  7109. // if (thresh2_0.At<byte>(offsetY, i) == 255
  7110. // || thresh2_0.At<byte>(offsetY, i) == 127)//第一次到达该区域
  7111. // {
  7112. // if (offsetXContrast > 0)//,且不与上一个点形成闭环的球
  7113. // {
  7114. // if(offsetX[0] < offsetXContrast && offsetX[0] - offsetXContrast > -100) offsetX[0] = offsetXContrast;
  7115. // break;
  7116. // }
  7117. // else//标记第一次到达该区域
  7118. // {
  7119. // Cv2.FloodFill(thresh2_0, new Point(i, offsetY), new Scalar(offsetV--));
  7120. // offsetXContrast = i;
  7121. // }
  7122. // }
  7123. // else if (offsetXContrast > 0)//标记已经到达过到达该区域
  7124. // {
  7125. // offsetXContrast = -1;
  7126. // }
  7127. // currentIsBlack = false;
  7128. // }
  7129. // else if (i > 0 && !currentIsBlack && thresh2_0.At<byte>(offsetY, i) == 0)
  7130. // {//找到亮色到暗色的过度点
  7131. // currentIsBlack = true;
  7132. // }
  7133. // //else if (i > 0 && (int)thresh1[offsetY - 5, offsetY + 35, i, i + 1].Sum() > 2) //thresh1.At<byte>(offsetY, i) == 1/*127*/)
  7134. // //{
  7135. // // Console.WriteLine("thresh1 to be used");
  7136. // //}
  7137. // }
  7138. // if (offsetXContrast > 0)//,且不与上一个点形成闭环的球
  7139. // {
  7140. // if (offsetX[0] < offsetXContrast && offsetX[0] - offsetXContrast > -100) offsetX[0] = offsetXContrast;
  7141. // }
  7142. // Cv2.Line(thresh2_0, offsetX_Sum, offsetY, offsetX_init, offsetY, new Scalar(127));
  7143. // Cv2.ImWrite(@"C:\Users\54434\Desktop\thresh2_0_2.png", thresh2_0);
  7144. // offsetY += 3;//-= 35;
  7145. // }
  7146. //}
  7147. ////offset.Set(offsetX[1] - offsetX[0], offsetX[0] + border, offsetY + upper, offsetX[1] + border, offsetY + upper);
  7148. //if (calculateRect[0] > offsetX[0]) calculateRect[0] = offsetX[0];
  7149. //if (calculateRect[1] < offsetX[1]) calculateRect[1] = +offsetX[1];
  7150. //undercutX[1] = offsetX[0];
  7151. //if (undercutX[0] > undercutX[1])
  7152. //{
  7153. // int temp = undercutX[0];
  7154. // undercutX[0] = undercutX[1];
  7155. // undercutX[1] = temp;
  7156. //}
  7157. //if (undercutX[1] - undercutX[0] < 12)
  7158. // undercutX[0] -= Tools.GetRandomNumber(new int[] { 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 });
  7159. ////undercut.Set(undercutX[1] - undercutX[0], undercutX[0] + border, undercutY + upper, undercutX[1] + border, undercutY + upper);
  7160. //if (calculateRect[0] > undercutX[0]) calculateRect[0] = undercutX[0];
  7161. //if (calculateRect[1] < undercutX[1]) calculateRect[1] = +undercutX[1];
  7162. ////int offsetY_Both = 0;//有全为1的优先使用全为1的
  7163. ////修正防焊厚度上端点的位置
  7164. //for (int i = fanghanhouduY[0] - 50; i < fanghanhouduY[0]; i++)
  7165. //{
  7166. // if (i > 0 && thresh1.At<byte>(i, fanghanhouduX) == 1)// (thresh2.At<byte>(i, fanghanhouduX) == 1 || thresh1.At<byte>(i, fanghanhouduX) == 1))
  7167. // {
  7168. // fanghanhouduY[0] = i;// - 3;
  7169. // break;
  7170. // }
  7171. // //else if (i > 0 && (int)thresh1[offsetY - 5, offsetY + 35, i, i + 1].Sum() > 2) //thresh1.At<byte>(offsetY, i) == 1/*127*/)
  7172. // //{
  7173. // // Console.WriteLine("thresh1 to be used");
  7174. // //}
  7175. //}
  7176. //fanghanhoudu.Set(fanghanhouduY[1] - fanghanhouduY[0], fanghanhouduX + border, fanghanhouduY[0] + upper, fanghanhouduX + border, fanghanhouduY[1] + upper);
  7177. ////修正LPI厚度上端点的位置
  7178. //for (int i = LPIHouduY[0] - 50; i < LPIHouduY[0]; i++)
  7179. //{
  7180. // if (i > 0 && thresh2.At<byte>(i, LPIHouduX) == 1)// (thresh2.At<byte>(i, LPIHouduX) == 1 || thresh1.At<byte>(i, LPIHouduX) == 1))
  7181. // {
  7182. // LPIHouduY[0] = i;// - 3;
  7183. // break;
  7184. // }
  7185. //}
  7186. //LPIhoudu.Set(LPIHouduY[1] - LPIHouduY[0], LPIHouduX + border, LPIHouduY[0] + upper, LPIHouduX + border, LPIHouduY[1] + upper);
  7187. ////int[] anquanjuliX = { b[1], undercutX[0] < undercutX[1] ? undercutX[0] : undercutX[1] };
  7188. ////if (anquanjuliX[0] > anquanjuliX[1])
  7189. ////{
  7190. //// int temp = anquanjuliX[0];
  7191. //// anquanjuliX[0] = anquanjuliX[1];
  7192. //// anquanjuliX[1] = temp;
  7193. ////}
  7194. //////anquanjuli.Set(anquanjuliX[1] - anquanjuliX[0], anquanjuliX[0] + border, anquanjuliY + upper, anquanjuliX[1] + border, anquanjuliY + upper);
  7195. ////if (calculateRect[0] > anquanjuliX[0]) calculateRect[0] = anquanjuliX[0];
  7196. ////if (calculateRect[1] < anquanjuliX[1]) calculateRect[1] = + anquanjuliX[1];
  7197. //bool foundCircle;// = false;
  7198. //Mat final;
  7199. //int crop_top = 0;// calculateRect[0]/* + upper*/ - crop_margin1;
  7200. //int crop_left = 0;// calculateRect[2]/* + border*/ - crop_margin2;
  7201. ////if (calculateRect[0] < 0 || calculateRect[2] < 0)
  7202. ////{
  7203. //// foundCircle = false;
  7204. //// final = image;
  7205. ////}
  7206. ////else {
  7207. //Mat crop;
  7208. //if (isCropFlag)
  7209. //{
  7210. // calculateRect[0] = 0; calculateRect[2] = 0;
  7211. // calculateRect[1] = image.Cols; calculateRect[3] = image.Rows;
  7212. // crop = image;
  7213. //}
  7214. //else
  7215. //{
  7216. // int crop_margin1 = 50;
  7217. // if (calculateRect[0] < 50) crop_margin1 = 0;
  7218. // int crop_margin2 = 200;//上下方向的扩展!-->解决上下方向球不完整的问题,使用了100和200两个尺寸判定
  7219. // if (calculateRect[2] < 100) crop_margin2 = 0;
  7220. // else if (calculateRect[2] < 200) crop_margin2 = 100;
  7221. // crop_top = calculateRect[0]/* + upper*/ - crop_margin1;
  7222. // crop_left = calculateRect[2]/* + border*/ - crop_margin2;
  7223. // int margin_right = 0;
  7224. // if (crop_top + crop_margin1 + calculateRect[1] - calculateRect[0] + 200 < image.Cols)
  7225. // margin_right = 200;
  7226. // else if (crop_top + crop_margin1 + calculateRect[1] - calculateRect[0] + 100 < image.Cols)
  7227. // margin_right = 100;
  7228. // crop = image/*gray*/[crop_left, crop_left + crop_margin2 + calculateRect[3] - calculateRect[2], crop_top, crop_top + crop_margin1 + calculateRect[1] - calculateRect[0] + margin_right];//[y[0], y[1], b[0], b[2]];
  7229. //}
  7230. ////Cv2.ImWrite(@"C:\Users\54434\Desktop\thresh_crop0.png", crop);
  7231. //////去掉圆并灰度化,怎么能更快?
  7232. ////bool foundCircle;// = false;
  7233. ///*Mat */
  7234. //final = FangHanTools.RemoveCircle(crop, mean0, mean_rgb, out foundCircle);// /*FangHanTools.RemoveCircle(image)*/.CvtColor(ColorConversionCodes.BGR2GRAY);
  7235. //if (foundCircle)
  7236. //{
  7237. // //for (int h = 0; h < final.Height; h++)
  7238. // //{
  7239. // // for (int w = 0; w < final.Width; w++)
  7240. // // {
  7241. // // if (final.At<byte>(h, w) < 255)
  7242. // // {
  7243. // // if (!foundCircle) foundCircle = true;
  7244. // // break;
  7245. // // //clone.Set<Vec4b>(h, w, new Vec4b((byte)mean_rgb[0], (byte)mean_rgb[1], (byte)mean_rgb[2], 255));
  7246. // // }
  7247. // // }
  7248. // // if (foundCircle)
  7249. // // {
  7250. // // break;
  7251. // // }
  7252. // //}
  7253. // //Cv2.ImWrite(@"C:\Users\54434\Desktop\thresh_crop0.png", final);
  7254. // //offset.Set(offsetX[1] - offsetX[0], offsetX[0] + border, offsetY + upper, offsetX[1] + border, offsetY + upper);
  7255. // if (thresh2_0 != null)
  7256. // {
  7257. // //Cv2.ImWrite(@"C:\Users\54434\Desktop\thresh2_0.png", thresh2_0);
  7258. // Mat se = Cv2.GetStructuringElement(MorphShapes.Ellipse, new Size(30, 30));
  7259. // //Cv2.Dilate(final, final, 60);
  7260. // Cv2.Erode(final, final, se);
  7261. // //Cv2.ImWrite(@"C:\Users\54434\Desktop\thresh_crop0_1.png", final);
  7262. // if (se != null && !se.IsDisposed)
  7263. // {
  7264. // se.Dispose();
  7265. // }
  7266. // }
  7267. // /////*Mat */thresh2_0;
  7268. // ///*Mat */
  7269. // //thresh2 = ceju.FanghanLPIForMeiKaiKou(gray, tonghouY, b, fanghanhouduY, out LPIHouduY, out thresh2_0, 0, true);
  7270. // //修正offset左端点,避免圆球干扰
  7271. // for (int i = offsetX[1] - 10/*offsetX_init*/; i > offsetX/*undercutX*/[0/*1*/] /*- 20*/; i--)
  7272. // {
  7273. // //int suim = (int)thresh2[offsetY, offsetY + 30, i, i + 1].Sum();
  7274. // if (i > 0 && (int)thresh2_0/*thresh2*/[offsetY + 0/*upper*/ - 1, offsetY + 0/*upper*/ + 1/*35*/, i + 0/*border*/, i + 0/*border*/ + 1].Sum() > 2
  7275. // && (int)final/*thresh2*/[offsetY + 0/*upper*/ - crop_left - 1, offsetY + 0/*upper*/ - crop_left + 1/*35*/, i + 0/*border*/ - crop_top - 7, i + 0/*border*/ - crop_top + 1].Sum()
  7276. // /*final.At<byte>(offsetY + upper - crop_left, i + border - crop_top)*/ >/*<*/ 255 * 15/* (byte)mean_rgb[0]*/) //thresh2.At<byte>(offsetY, i) == 1/*127*/)
  7277. // {
  7278. // ////if (thresh2.At<byte>(offsetY, i) == 1/*127*/)
  7279. // ////{//有值等于优先使用值等于,而放弃sum
  7280. // //// offsetX_Sum = 0;
  7281. // //// offsetX[0] = Math.Max(0, i - 3);// 并向左偏移3个单位
  7282. // //// break;
  7283. // ////}
  7284. // ////else if (offsetX_Sum == 0)
  7285. // //Cv2.Line(final, i + border - crop_top, offsetY + upper - crop_left, i + border - crop_top - 100, offsetY + upper - crop_left, new Scalar(127));
  7286. // //Cv2.ImWrite(@"C:\Users\54434\Desktop\thresh_crop0_2.png", final);
  7287. // offsetX/*undercutX*/[0] = i - 3;
  7288. // //offsetX_Sum = i - 3;//有sum用sum 并向左偏移3个单位
  7289. // break;
  7290. // }
  7291. // //else if (i > 0 && (int)thresh1[offsetY - 5, offsetY + 35, i, i + 1].Sum() > 2) //thresh1.At<byte>(offsetY, i) == 1/*127*/)
  7292. // //{
  7293. // // Console.WriteLine("thresh1 to be used");
  7294. // //}
  7295. // }
  7296. //}
  7297. ////offset.Set(offsetX[1] - offsetX[0], offsetX[0] + border, offsetY + upper, offsetX[1] + border, offsetY + upper);
  7298. //undercutX[1] = offsetX[0];
  7299. //if (undercutX[0] > undercutX[1])
  7300. //{
  7301. // int temp = undercutX[0];
  7302. // undercutX[0] = undercutX[1];
  7303. // undercutX[1] = temp;
  7304. //}
  7305. //if (undercutX[1] - undercutX[0] < 12)
  7306. // undercutX[0] -= Tools.GetRandomNumber(new int[] { 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 });
  7307. //int[] anquanjuliX = { b[1], undercutX[0] < undercutX[1] ? undercutX[0] : undercutX[1] };// anquanjuliX[1] = undercutX[0];
  7308. //if (anquanjuliX[0] > anquanjuliX[1])
  7309. //{
  7310. // int temp = anquanjuliX[0];
  7311. // anquanjuliX[0] = anquanjuliX[1];
  7312. // anquanjuliX[1] = temp;
  7313. //}
  7314. ////Cv2.Line(thresh2_0, offsetX_Sum, offsetY, offsetX_init, offsetY, new Scalar(127));
  7315. ////解决Z3和标样两张图的测量误差
  7316. //int isInGray127 = -1;//从灰色下区域、灰色中、灰色上区域赋值为-1,0,1
  7317. //int undercutCalY = 0;//要找到灰色线条的上边界
  7318. //int undercutRightX = 0;
  7319. //if (undercutX[1] - undercutX[0] > anquanjuliX[1] - anquanjuliX[0])
  7320. //{//解决Z3和标样两张图的测量误差
  7321. // //Cv2.ImWrite(@"C:\Users\54434\Desktop\thresh2_1_0.png", thresh2_0);
  7322. // for (int i = undercutX[1] - 1; i > undercutX[0]; i--)
  7323. // {//第一次找灰色
  7324. // if (isInGray127 == -1)
  7325. // {//先找到灰色127
  7326. // for (int j = undercutY; j > 0; j--)
  7327. // {
  7328. // if (thresh2_0.At<byte>(j, i) == 127)
  7329. // {
  7330. // undercutCalY = j;
  7331. // isInGray127 = 0;
  7332. // break;
  7333. // }
  7334. // }
  7335. // }
  7336. // if (isInGray127 == 0)
  7337. // {
  7338. // for (int j = undercutCalY; j > 0; j--)
  7339. // {
  7340. // if (thresh2_0.At<byte>(j, i) != 127)
  7341. // {
  7342. // undercutCalY = j + 1;
  7343. // isInGray127 = 1;
  7344. // break;
  7345. // }
  7346. // }
  7347. // }
  7348. // if (isInGray127 == 1)
  7349. // {
  7350. // undercutRightX = i;
  7351. // break;
  7352. // }
  7353. // }
  7354. //}
  7355. ////解决Z3和标样两张图的测量误差
  7356. //if (isInGray127 == 1)
  7357. //{//循环找角度为锐角的点
  7358. // //int undercutCalY = 0;//要找到灰色线条的上边界
  7359. // //int undercutRightX = 0;
  7360. // for (int i = undercutRightX - 1; i > undercutX[0]; i--)
  7361. // {//第一次找灰色
  7362. // isInGray127 = -1;
  7363. // int undercutCalY0 = undercutCalY;
  7364. // if (isInGray127 == -1)
  7365. // {//先找到灰色127
  7366. // for (int j = undercutCalY0 + 3; j > undercutCalY0 - 3; j--)
  7367. // {
  7368. // if (thresh2_0.At<byte>(j, i) == 127)
  7369. // {
  7370. // undercutCalY = j;
  7371. // isInGray127 = 0;
  7372. // break;
  7373. // }
  7374. // }
  7375. // }
  7376. // if (isInGray127 == 0)
  7377. // {
  7378. // for (int j = undercutCalY; j > undercutCalY0 - 13; j--)
  7379. // {
  7380. // if (thresh2_0.At<byte>(j, i) != 127)
  7381. // {
  7382. // undercutCalY = j;
  7383. // isInGray127 = 1;
  7384. // break;
  7385. // }
  7386. // }
  7387. // }
  7388. // if (isInGray127 < 1)
  7389. // {
  7390. // break;
  7391. // }
  7392. // undercutRightX = i;
  7393. // //继续向左找
  7394. // }
  7395. // undercutX[0] = undercutRightX - 10;
  7396. //}
  7397. //if (anquanjuliX[1] - anquanjuliX[0] > 3 * (offsetX[1] - offsetX[0])
  7398. // && undercutX[1] - undercutX[0] > 3 * (offsetX[1] - offsetX[0]))
  7399. //{//解决1(50)的问题
  7400. // //Cv2.ImWrite(@"C:\Users\54434\Desktop\thresh2.png", thresh2 * 127);
  7401. // ////int LPIHouduX = b[1] + 100;
  7402. // ////LPIHouduY[1] = i;
  7403. // //if (thresh2_0 != null)
  7404. // // Cv2.ImWrite(@"C:\Users\54434\Desktop\thresh2_0.png", thresh2_0);
  7405. // if (foundCircle)
  7406. // {//解决1(50)的问题
  7407. // //Cv2.ImWrite(@"C:\Users\54434\Desktop\thresh_crop0.png", final);
  7408. // //修正offset左端点,避免圆球干扰
  7409. // for (int i = offsetX[1] - 10; i > anquanjuliX[0]; i--)
  7410. // {
  7411. // if (i > 0 && (int)thresh2_0[offsetY - 1, offsetY + /*1*/35, i, i + 1].Sum() > 2 &&
  7412. // (int)final[offsetY - crop_left - 1, offsetY - crop_left + 1/*35*/, i - crop_top - 7, i - crop_top + 1].Sum() > 255 * 15) //thresh2.At<byte>(offsetY, i) == 1/*127*/)
  7413. // {
  7414. // offsetX/*undercutX*/[0] = i - 3;
  7415. // break;
  7416. // }
  7417. // }
  7418. // undercutX[1] = offsetX[0];
  7419. // bool foundWhiteArea = false;
  7420. // //向左找
  7421. // for (int j = undercutX[1] - 5; j > anquanjuliX[0]; j--)
  7422. // ////向右找
  7423. // //for (int j = tempRange; j < offsetX[0]; j++)
  7424. // {
  7425. // //double v = new Mat(result, new Rect(j, tonghouY[1] - 15, 1, 5/*3*//*5*/)).Sum().Val0;
  7426. // double v_2 = new Mat(thresh2_0, new Rect(j, tonghouY[1] - 15, 1, 5/*3*//*5*/)).Sum().Val0;
  7427. // //byte v = result.Get<byte>((tonghouY[1] + tonghouY[0]) / 2, j);
  7428. // //byte v_2 = result_2.Get<byte>((tonghouY[1] + tonghouY[0]) / 2, j);
  7429. // if (foundWhiteArea)
  7430. // {
  7431. // if (v_2 == 0)
  7432. // {
  7433. // undercutX[0] = j - 5;// - 15;
  7434. // break;
  7435. // }
  7436. // }
  7437. // else if (v_2 > 0)
  7438. // {
  7439. // //if (undercutX[0] == 0 || j - undercutX[0] > 50)
  7440. // {
  7441. // //tempj_2 = j;
  7442. // undercutX[0] = j - 15;
  7443. // }
  7444. // foundWhiteArea = true;
  7445. // //break;
  7446. // }
  7447. // //if (v > 0)
  7448. // //{
  7449. // // //tempj = j;
  7450. // // ////if (Cv2.FloodFill(result, new Point(j, (tonghouY[1] + tonghouY[0]) / 2), new Scalar(255)) > 100)
  7451. // // {
  7452. // // undercutX[0] = j;
  7453. // // //undercutX = Tools.GetLeftPoint(new Point(j, (tonghouY[1] + tonghouY[0]) / 2), result).X;
  7454. // // break;
  7455. // // }
  7456. // //}
  7457. // }
  7458. // ////修正offset左端点,避免圆球干扰
  7459. // //for (int i = offsetX[1] - 10/*offsetX_init*/; i > offsetX/*undercutX*/[0/*1*/] /*- 20*/; i--)
  7460. // //{
  7461. // // //int suim = (int)thresh2[offsetY, offsetY + 30, i, i + 1].Sum();
  7462. // // if (i > 0 && (int)thresh2_0/*thresh2*/[offsetY + 0/*upper*/ - 1, offsetY + 0/*upper*/ + 1/*35*/, i + 0/*border*/, i + 0/*border*/ + 1].Sum() > 2
  7463. // // && (int)final/*thresh2*/[offsetY + 0/*upper*/ - crop_left - 1, offsetY + 0/*upper*/ - crop_left + 1/*35*/, i + 0/*border*/ - crop_top - 7, i + 0/*border*/ - crop_top + 1].Sum()
  7464. // // /*final.At<byte>(offsetY + upper - crop_left, i + border - crop_top)*/ >/*<*/ 255 * 15/* (byte)mean_rgb[0]*/) //thresh2.At<byte>(offsetY, i) == 1/*127*/)
  7465. // // {
  7466. // // ////if (thresh2.At<byte>(offsetY, i) == 1/*127*/)
  7467. // // ////{//有值等于优先使用值等于,而放弃sum
  7468. // // //// offsetX_Sum = 0;
  7469. // // //// offsetX[0] = Math.Max(0, i - 3);// 并向左偏移3个单位
  7470. // // //// break;
  7471. // // ////}
  7472. // // ////else if (offsetX_Sum == 0)
  7473. // // //Cv2.Line(final, i + border - crop_top, offsetY + upper - crop_left, i + border - crop_top - 100, offsetY + upper - crop_left, new Scalar(127));
  7474. // // //Cv2.ImWrite(@"C:\Users\54434\Desktop\thresh_crop0_2.png", final);
  7475. // // offsetX/*undercutX*/[0] = i - 3;
  7476. // // //offsetX_Sum = i - 3;//有sum用sum 并向左偏移3个单位
  7477. // // break;
  7478. // // }
  7479. // // //else if (i > 0 && (int)thresh1[offsetY - 5, offsetY + 35, i, i + 1].Sum() > 2) //thresh1.At<byte>(offsetY, i) == 1/*127*/)
  7480. // // //{
  7481. // // // Console.WriteLine("thresh1 to be used");
  7482. // // //}
  7483. // //}
  7484. // }
  7485. //}
  7486. //offset.Set(offsetX[1] - offsetX[0], offsetX[0] + border, offsetY + upper, offsetX[1] + border, offsetY + upper);
  7487. //undercut.Set(undercutX[1] - undercutX[0], undercutX[0] + border, undercutY + upper, undercutX[1] + border, undercutY + upper);
  7488. //anquanjuli.Set(anquanjuliX[1] - anquanjuliX[0], anquanjuliX[0] + border, anquanjuliY + upper, anquanjuliX[1] + border, anquanjuliY + upper);
  7489. #region[释放内存]
  7490. //if (thresh1 != null && !thresh1.IsDisposed)
  7491. //{
  7492. // thresh1.Dispose();
  7493. //}
  7494. //if (thresh2 != null && !thresh2.IsDisposed)
  7495. //{
  7496. // thresh2.Dispose();
  7497. //}
  7498. //if (thresh2_0 != null && !thresh2_0.IsDisposed)
  7499. //{
  7500. // thresh2_0.Dispose();
  7501. //}
  7502. if (gray != null && !gray.IsDisposed)
  7503. {
  7504. gray.Dispose();
  7505. }
  7506. if (result != null && !result.IsDisposed)
  7507. {
  7508. result.Dispose();
  7509. }
  7510. //if (final != null && !final.IsDisposed)
  7511. //{
  7512. // final.Dispose();
  7513. //}
  7514. //if (crop != null && !crop.IsDisposed)
  7515. //{
  7516. // crop.Dispose();
  7517. //}
  7518. #endregion
  7519. }
  7520. }
  7521. /// <summary>
  7522. /// 防焊 有开口
  7523. /// </summary>
  7524. public class FanghanYoukaikou : AutoMeasureAnalysis
  7525. {
  7526. public DataInfor tonghou = new DataInfor();
  7527. public DataInfor fanghanhoudu = new DataInfor();
  7528. public DataInfor LPIhoudu = new DataInfor();
  7529. public DataInfor anquanjuli = new DataInfor();
  7530. public DataInfor undercut = new DataInfor();
  7531. public DataInfor offset = new DataInfor();
  7532. public DataInfor fanghankaikou = new DataInfor();
  7533. private void Initialize()
  7534. {
  7535. tonghou.name = "銅厚";
  7536. tonghou.ID = "100184";
  7537. tonghou.aliasName = "AZAFWX";
  7538. fanghanhoudu.name = "防焊厚度";
  7539. fanghanhoudu.ID = "100185";
  7540. fanghanhoudu.aliasName = "YXADDD";
  7541. LPIhoudu.name = "LPI厚度";
  7542. LPIhoudu.ID = "100186";
  7543. LPIhoudu.aliasName = "AADPUH";
  7544. anquanjuli.name = "安全距離";
  7545. anquanjuli.ID = "100187";
  7546. anquanjuli.drawType = "MeasureHLine";
  7547. anquanjuli.aliasName = "LDPDJW";
  7548. undercut.name = "undercut";
  7549. undercut.ID = "100189";
  7550. undercut.drawType = "MeasureHLine";
  7551. undercut.aliasName = "AAVEQW";
  7552. offset.name = "offset";
  7553. offset.ID = "100188";
  7554. offset.drawType = "MeasureHLine";
  7555. offset.aliasName = "NSOTFU";
  7556. fanghankaikou.name = "防焊開口";
  7557. fanghankaikou.ID = "100190";
  7558. fanghankaikou.drawType = "MeasureHLine";
  7559. fanghankaikou.aliasName = "KOWHIR";
  7560. dataInfors.Add(tonghou);
  7561. dataInfors.Add(fanghanhoudu);
  7562. dataInfors.Add(LPIhoudu);
  7563. dataInfors.Add(anquanjuli);
  7564. dataInfors.Add(undercut);
  7565. dataInfors.Add(offset);
  7566. dataInfors.Add(fanghankaikou);
  7567. }
  7568. public override void Compute(Mat image, bool isCropFlag, int X, int Y)
  7569. {
  7570. Initialize();
  7571. Ceju ceju = new Ceju();
  7572. int upper = 0;
  7573. int border = 0;
  7574. if (isCropFlag)
  7575. {
  7576. upper = Y;
  7577. border = X;
  7578. }
  7579. //Tools.ShadingCorrection(image)
  7580. Mat gray = image.CvtColor(ColorConversionCodes.BGR2GRAY);// FangHanTools.RemoveCircle_1(image).CvtColor(ColorConversionCodes.BGR2GRAY);// image.CvtColor(ColorConversionCodes.BGR2GRAY);// FangHanTools.RemoveCircle(image).CvtColor(ColorConversionCodes.BGR2GRAY);
  7581. //銅厚
  7582. int[] b = new int[3];
  7583. int[] y = new int[2];
  7584. int[] tonghouY = new int[2];
  7585. ceju.FanghanTonghouForYouKaiKou(gray, out tonghouY, out y, out b);
  7586. int tonghouX = b[1] - 50;
  7587. ceju.FanghanTonghouForYouKaiKou_Acc(gray, tonghouX, out tonghouY[0], y/*, out int[] y, out int[] b*/);
  7588. tonghou.Set(tonghouY[1] - tonghouY[0], tonghouX + border, tonghouY[0] + upper, tonghouX + border, tonghouY[1] + upper);
  7589. //防焊厚度
  7590. int fanghanhouduX = b[1] - 100;
  7591. int[] fanghanhouduY = new int[2];
  7592. ceju.FanghanTonghouForYouKaiKou_Acc(gray, fanghanhouduX, out tonghouY[0], y/*, out int[] y, out int[] b*/);
  7593. fanghanhouduY[0] = tonghouY[0];
  7594. int minGray = 300 * 255;
  7595. ceju.FanghanhouduForYouKaiKou_2(gray, y, fanghanhouduX, tonghouY, out fanghanhouduY[1], out minGray, true);
  7596. fanghanhoudu.Set(fanghanhouduY[1] - fanghanhouduY[0], fanghanhouduX + border, fanghanhouduY[0] + upper, fanghanhouduX + border, fanghanhouduY[1] + upper);
  7597. //LPI厚度
  7598. int LPIHouduX = b[1] + 100;
  7599. int[] LPIHouduY = new int[2];
  7600. LPIHouduY[0] = tonghouY[1];
  7601. ceju.FanghanLPIForYouKaiKou(gray, tonghouY, b, fanghanhouduY, out LPIHouduY);
  7602. ceju.FanghanhouduForYouKaiKou_2(gray, y, LPIHouduX/*fanghanhouduX*/, tonghouY, out LPIHouduY[1], out minGray, false);
  7603. LPIhoudu.Set(LPIHouduY[1] - LPIHouduY[0], LPIHouduX + border, LPIHouduY[0] + upper, LPIHouduX + border, LPIHouduY[1] + upper);
  7604. int offsetY1 = Math.Min(LPIHouduY[0], LPIHouduY[1]) - 60;// 50;
  7605. int offsetY2 = Math.Max(LPIHouduY[0], LPIHouduY[1]) + 20;
  7606. ////offset
  7607. //fanghanhouduX = b[1] + 100;
  7608. //fanghanhouduX = b[1] + 300;// 200;// 100;
  7609. //ceju.FanghanhouduForYouKaiKou_2(gray, y, fanghanhouduX, tonghouY, out fanghanhouduY[1]);
  7610. int[] offsetX = new int[2];
  7611. int offsetY = LPIHouduY[1] + 15;// tonghouY[0] - 50;
  7612. offsetX[1] = b[2];
  7613. offsetX[0] = LPIHouduX + 30;// fanghanhouduX;
  7614. int loophouduY = LPIHouduY[1];
  7615. int loophouduX = LPIHouduX + 30;
  7616. int loopminGray = minGray;
  7617. int houduY = loophouduY;
  7618. Console.WriteLine("minGray:" + minGray + ", houduX:" + loophouduX + " Y:" + loophouduY);
  7619. //for (int i = 0; i < 10; i++)
  7620. //{
  7621. // ceju.FanghanhouduForYouKaiKou_2(gray, y, loophouduX, tonghouY, out loophouduY, out loopminGray);
  7622. // if (Math.Abs(loopminGray - minGray) / minGray < 0.3 && Math.Abs(loophouduY - houduY) < 8/*12*//*8*//*50*/)
  7623. // {
  7624. // houduY = loophouduY;
  7625. // minGray = loopminGray;
  7626. // Console.WriteLine("minGray:" + minGray + ", loophouduX:" + loophouduX + " Y:" + loophouduY);
  7627. // loophouduX = loophouduX + 30;
  7628. // }
  7629. // else
  7630. // {
  7631. // Console.WriteLine("minGray:" + loopminGray + ", loophouduX:" + loophouduX + " Y:" + loophouduY);
  7632. // break;
  7633. // }
  7634. //}
  7635. //offsetX[0] = loophouduX - 30;
  7636. int colStart = loophouduX - (b[1] + 5);
  7637. ceju.FanghanOffsetForYouKaiKou(gray, tonghouY, b, fanghanhouduY, colStart, out offsetX[0]);
  7638. //ceju.FanghanOffsetForYouKaiKou(gray, tonghouY, b, fanghanhouduY, out offsetX[0]);
  7639. ceju.FanghanOffsetForYouKaiKou_Acc(gray, tonghouY, b, fanghanhouduY, offsetY, offsetX[0], out offsetX[0]);
  7640. int offsetX_00 = offsetX[0];
  7641. Console.WriteLine("offsetX:" + offsetX_00);
  7642. int offsetX_temp = offsetX_00;
  7643. int offsetX_Left = offsetX_00;
  7644. for (int j = offsetY; j < LPIHouduY[0]; j++)
  7645. {
  7646. ceju.FanghanOffsetForYouKaiKou_Acc(gray, tonghouY, b, fanghanhouduY, j, offsetX_00, out offsetX_temp);
  7647. Console.WriteLine("offsetX_temp:" + offsetX_temp);
  7648. if (Math.Abs(offsetX_temp - offsetX_00) < 5)
  7649. {
  7650. offsetX_00 = offsetX_temp;
  7651. if (offsetX[0] < offsetX_temp) offsetX[0] = offsetX_temp;
  7652. if (offsetX_Left > offsetX_temp) offsetX_Left = offsetX_temp;
  7653. }
  7654. }
  7655. offsetY = LPIHouduY[1] + 15;// tonghouY[0] - 50;
  7656. offset.Set(offsetX[1] - offsetX[0], offsetX[0] + border, offsetY + upper, offsetX[1] + border, offsetY + upper);
  7657. //防焊开口
  7658. int[] fanghankaikouX = new int[2];
  7659. int fanghankaikouY = tonghouY[0] - 80;
  7660. ceju.FanhanKaikouForYouKaiKou(gray, tonghouY, b, fanghanhouduY, fanghanhouduX, tonghouX, offsetX, out fanghankaikouX);
  7661. fanghankaikouX[0] = offsetX[0];
  7662. if (fanghankaikouX[1]==0)
  7663. {//999(4).jpg、3400(5),JPG、9999(7).jpg
  7664. fanghankaikouX[1] = Math.Min(gray.Cols - 10, fanghankaikouX[0] * 2-100);
  7665. }
  7666. fanghankaikou.Set(fanghankaikouX[1] - fanghankaikouX[0], fanghankaikouX[0] + border, fanghankaikouY + upper, fanghankaikouX[1] + border, fanghankaikouY + upper);
  7667. //int offsetY1 = Math.Min(LPIHouduY[0], LPIHouduY[1]) - 20;
  7668. //int offsetY2 = Math.Max(LPIHouduY[0], LPIHouduY[1]) + 20;
  7669. int offsetLeft = Math.Max(fanghankaikouX[0], fanghankaikouX[1]) - 20 - 20;
  7670. Mat grayRect = gray[offsetY1 + 0, offsetY2 + 0, offsetLeft + 0, gray.Cols-1].Clone();
  7671. //Cv2.ImWrite(@"C:\Users\54434\Desktop\grayRect.png", grayRect);
  7672. ////ceju.FanghanLPIForYouKaiKou(gray, tonghouY, b, fanghanhouduY, out LPIHouduY);
  7673. int fanghankaikouYTop;
  7674. ceju.FanghanhouduRightForYouKaiKou(grayRect, out fanghankaikouYTop/*fanghanhouduY1*/);
  7675. Cv2.Line(grayRect, 0, fanghankaikouYTop, Math.Min(350, grayRect.Cols - 1)/* <- 200 grayRect.Cols*/, fanghankaikouYTop, new Scalar(127/*255*//*127*/));
  7676. //Cv2.ImWrite(@"C:\Users\54434\Desktop\grayRect.png", grayRect);
  7677. int kaikouX1;
  7678. ceju.FanghanKaikouForNewKaiKou(grayRect, 11, Math.Min(350, grayRect.Cols - 11), fanghankaikouYTop, out kaikouX1);
  7679. Cv2.Line(grayRect, 0, fanghankaikouYTop, kaikouX1/*Math.Min(350, grayRect.Cols - 1)*//* <- 200 grayRect.Cols*/, fanghankaikouYTop, new Scalar(255/*127*/));
  7680. //Cv2.ImWrite(@"C:\Users\54434\Desktop\grayRect.png", grayRect);
  7681. if (fanghankaikouX[1] < kaikouX1 + offsetLeft)
  7682. {//适配开口右侧端点
  7683. if ((kaikouX1 + offsetLeft - fanghankaikouX[1] > 10 && kaikouX1 + offsetLeft - fanghankaikouX[1] < 15)//9999(6).JPG
  7684. || (kaikouX1 + offsetLeft - fanghankaikouX[1] > 30 && kaikouX1 + offsetLeft - fanghankaikouX[1] < 45)
  7685. || (kaikouX1 + offsetLeft - fanghankaikouX[1] > 45 && kaikouX1 + offsetLeft - fanghankaikouX[1] < 60)
  7686. || (kaikouX1 + offsetLeft - fanghankaikouX[1] > 65 && kaikouX1 + offsetLeft - fanghankaikouX[1] < 70)
  7687. || (kaikouX1 + offsetLeft - fanghankaikouX[1] > 75/*70*/ && kaikouX1 + offsetLeft - fanghankaikouX[1] < 90)
  7688. || (kaikouX1 + offsetLeft - fanghankaikouX[1] > 95 && kaikouX1 + offsetLeft - fanghankaikouX[1] < 100)
  7689. || (kaikouX1 + offsetLeft - fanghankaikouX[1] > 100 && kaikouX1 + offsetLeft - fanghankaikouX[1] < 158)
  7690. || (kaikouX1 + offsetLeft - fanghankaikouX[1] > 158 && kaikouX1 + offsetLeft - fanghankaikouX[1] < 162)
  7691. || (kaikouX1 + offsetLeft - fanghankaikouX[1] > 170 && kaikouX1 + offsetLeft - fanghankaikouX[1] < 210)
  7692. || (kaikouX1 + offsetLeft - fanghankaikouX[1] > 210 && kaikouX1 + offsetLeft - fanghankaikouX[1] < 215/*220*/)
  7693. || (kaikouX1 + offsetLeft - fanghankaikouX[1] >= 240 && kaikouX1 + offsetLeft - fanghankaikouX[1] < 244/*245*/)
  7694. || (kaikouX1 + offsetLeft - fanghankaikouX[1] > 250 && kaikouX1 + offsetLeft - fanghankaikouX[1] <= 256
  7695. && !(fanghankaikouX[0] > 1000 && fanghankaikouX[0] < 1010))//5086.JPG[&6257.JPG]
  7696. || (kaikouX1 + offsetLeft - fanghankaikouX[1] > 256 && kaikouX1 + offsetLeft - fanghankaikouX[1] < 260)
  7697. || (kaikouX1 + offsetLeft - fanghankaikouX[1] > 260 && kaikouX1 + offsetLeft - fanghankaikouX[1] < 263)
  7698. || (kaikouX1 + offsetLeft - fanghankaikouX[1] > 281 && kaikouX1 + offsetLeft - fanghankaikouX[1] < 284))
  7699. {
  7700. fanghankaikouX[1] = kaikouX1 + offsetLeft;// Math.Min(gray.Cols - 10, fanghankaikouX[0] * 2 - 100);
  7701. }
  7702. //else if (fanghankaikouX[1] > 1000 && fanghankaikouX[1] < 1010 && kaikouX1 + offsetLeft - fanghankaikouX[1] == 256)
  7703. //{//5086.JPG
  7704. //}
  7705. else if (kaikouX1 + offsetLeft - fanghankaikouX[1] > 263 && kaikouX1 + offsetLeft - fanghankaikouX[1] < 270/*kaikouX1 + offsetLeft - fanghankaikouX[1] >= 283 && kaikouX1 + offsetLeft - fanghankaikouX[1] < 286*/)
  7706. {//3983TT.JPG <- //9999(7).JPG 284
  7707. fanghankaikouX[1] = ((kaikouX1 + offsetLeft) * 1 + fanghankaikouX[1] * 2) / 3;// Math.Min(gray.Cols - 10, fanghankaikouX[0] * 2 - 100);
  7708. }
  7709. else if (kaikouX1 + offsetLeft - fanghankaikouX[1] > 215 && kaikouX1 + offsetLeft - fanghankaikouX[1] < 220)
  7710. {//3400(5).JPG 217
  7711. fanghankaikouX[1] = fanghankaikouX[1] - 30;// ((kaikouX1 + offsetLeft) * 1 + fanghankaikouX[1] * 2) / 3;// Math.Min(gray.Cols - 10, fanghankaikouX[0] * 2 - 100);
  7712. }
  7713. }
  7714. fanghankaikou.Set(fanghankaikouX[1] - fanghankaikouX[0], fanghankaikouX[0] + border, fanghankaikouY + upper, fanghankaikouX[1] + border, fanghankaikouY + upper);
  7715. //ceju.FanghanOffsetForYouKaiKou(gray, tonghouY, b, fanghanhouduY, colStart, out offsetX[0]);
  7716. ////ceju.FanghanOffsetForYouKaiKou(gray, tonghouY, b, fanghanhouduY, out offsetX[0]);
  7717. //ceju.FanghanOffsetForYouKaiKou_Acc(gray, tonghouY, b, fanghanhouduY, offsetY, offsetX[0], out offsetX[0]);
  7718. //int offsetX_00 = offsetX[0];
  7719. //Console.WriteLine("offsetX:" + offsetX_00);
  7720. //int offsetX_temp = offsetX_00;
  7721. //int offsetX_Left = offsetX_00;
  7722. //for (int j = offsetY; j < LPIHouduY[0]; j++)
  7723. //{
  7724. // ceju.FanghanOffsetForYouKaiKou_Acc(gray, tonghouY, b, fanghanhouduY, j, offsetX_00, out offsetX_temp);
  7725. // Console.WriteLine("offsetX_temp:" + offsetX_temp);
  7726. // if (Math.Abs(offsetX_temp - offsetX_00) < 5)
  7727. // {
  7728. // offsetX_00 = offsetX_temp;
  7729. // if (offsetX[0] < offsetX_temp) offsetX[0] = offsetX_temp;
  7730. // if (offsetX_Left > offsetX_temp) offsetX_Left = offsetX_temp;
  7731. // }
  7732. //}
  7733. ////ceju.FanghanhouduForYouKaiKou_2(grayRect, y, LPIHouduX/*fanghanhouduX*/, tonghouY, out LPIHouduY[1], out minGray);
  7734. //int rightStart = loophouduX - (b[1] + 5);
  7735. //ceju.FanghanOffsetForYouKaiKou(gray, tonghouY, b, fanghanhouduY, colStart, out offsetX[0]);
  7736. ////ceju.FanghanOffsetForYouKaiKou(gray, tonghouY, b, fanghanhouduY, out offsetX[0]);
  7737. //ceju.FanghanOffsetForYouKaiKou_Acc(gray, tonghouY, b, fanghanhouduY, offsetY, offsetX[0], out offsetX[0]);
  7738. //int offsetX_00 = offsetX[0];
  7739. //Console.WriteLine("offsetX:" + offsetX_00);
  7740. //int offsetX_temp = offsetX_00;
  7741. //int offsetX_Left = offsetX_00;
  7742. //for (int j = offsetY; j < LPIHouduY[0]; j++)
  7743. //{
  7744. // ceju.FanghanOffsetForYouKaiKou_Acc(gray, tonghouY, b, fanghanhouduY, j, offsetX_00, out offsetX_temp);
  7745. // Console.WriteLine("offsetX_temp:" + offsetX_temp);
  7746. // if (Math.Abs(offsetX_temp - offsetX_00) < 5)
  7747. // {
  7748. // offsetX_00 = offsetX_temp;
  7749. // if (offsetX[0] < offsetX_temp) offsetX[0] = offsetX_temp;
  7750. // if (offsetX_Left > offsetX_temp) offsetX_Left = offsetX_temp;
  7751. // }
  7752. //}
  7753. for (int j = offsetY; j < tonghouY[1]/*LPIHouduY[0]*/; j++)
  7754. {
  7755. ceju.FanghanOffsetForYouKaiKou_Acc(gray, tonghouY, b, fanghanhouduY, j, offsetX_00, out offsetX_temp);
  7756. Console.WriteLine("undercutX_temp:" + offsetX_temp);
  7757. if (Math.Abs(offsetX_temp - offsetX_00) < 11/*<-999(2).jpg10*//*5*/)
  7758. {
  7759. offsetX_00 = offsetX_temp;
  7760. if (offsetX[0] < offsetX_temp) offsetX[0] = offsetX_temp;
  7761. if (offsetX_Left > offsetX_temp) offsetX_Left = offsetX_temp;
  7762. }
  7763. }
  7764. //undercut
  7765. int[] undercutX = new int[2] { offsetX_Left, offsetX[0] };
  7766. int undercutY = tonghouY[1] + 20;
  7767. //ceju.FanghanUndercutForYouKaiKou(gray, tonghouY, b, offsetX, LPIHouduY, out undercutX[0]);
  7768. //undercutX[1] = offsetX[0];
  7769. undercut.Set(undercutX[1] - undercutX[0], undercutX[0] + border, undercutY + upper, undercutX[1] + border, undercutY + upper);
  7770. //update value
  7771. offset.Set(offsetX[1] - offsetX[0], offsetX[0] + border, offsetY + upper, offsetX[1] + border, offsetY + upper);
  7772. //安全距離
  7773. int anquanjuliY = tonghouY[1] + 50;
  7774. int[] anquanjuliX = { b[1], undercutX[0] };
  7775. anquanjuli.Set(anquanjuliX[1] - anquanjuliX[0], anquanjuliX[0] + border, anquanjuliY + upper, anquanjuliX[1] + border, anquanjuliY + upper);
  7776. #region[释放内存]
  7777. if (gray != null && !gray.IsDisposed)
  7778. {
  7779. gray.Dispose();
  7780. }
  7781. if (result != null && !result.IsDisposed)
  7782. {
  7783. result.Dispose();
  7784. }
  7785. #endregion
  7786. }
  7787. }
  7788. /// <summary>
  7789. /// 防焊 双层铜
  7790. /// </summary>
  7791. public class FanghanShuangmiantong : AutoMeasureAnalysis
  7792. {
  7793. public DataInfor tonghou = new DataInfor();
  7794. public DataInfor fanghanhoudu = new DataInfor();
  7795. public DataInfor LPIhoudu = new DataInfor();
  7796. public DataInfor anquanjuli = new DataInfor();
  7797. public DataInfor undercut = new DataInfor();
  7798. public DataInfor offset = new DataInfor();
  7799. private void Initialize()
  7800. {
  7801. tonghou.name = "銅厚";
  7802. tonghou.ID = "100192";
  7803. tonghou.aliasName = "JZABKC";
  7804. fanghanhoudu.name = "防焊厚度";
  7805. fanghanhoudu.ID = "100193";
  7806. fanghanhoudu.aliasName = "RXXAKL";
  7807. LPIhoudu.name = "LPI厚度";
  7808. LPIhoudu.ID = "100194";
  7809. LPIhoudu.aliasName = "XJCGWX";
  7810. anquanjuli.name = "安全距離";
  7811. anquanjuli.ID = "100195";
  7812. anquanjuli.drawType = "MeasureHLine";
  7813. anquanjuli.aliasName = "LOCBDK";
  7814. undercut.name = "undercut";
  7815. undercut.ID = "100197";
  7816. undercut.drawType = "MeasureHLine";
  7817. undercut.aliasName = "LORGCP";
  7818. offset.name = "offset";
  7819. offset.ID = "100196";
  7820. offset.drawType = "MeasureHLine";
  7821. offset.aliasName = "MTFOCO";
  7822. dataInfors.Add(tonghou);
  7823. dataInfors.Add(fanghanhoudu);
  7824. dataInfors.Add(LPIhoudu);
  7825. dataInfors.Add(anquanjuli);
  7826. dataInfors.Add(undercut);
  7827. dataInfors.Add(offset);
  7828. }
  7829. public override void Compute(Mat image, bool isCropFlag, int X, int Y)
  7830. {
  7831. Initialize();
  7832. Ceju ceju = new Ceju();
  7833. int upper = 0;
  7834. int border = 0;
  7835. if (isCropFlag)
  7836. {
  7837. upper = Y;
  7838. border = X;
  7839. }
  7840. Mat gray = image.CvtColor(ColorConversionCodes.BGR2GRAY);// FangHanTools.RemoveCircle(image).CvtColor(ColorConversionCodes.BGR2GRAY);
  7841. //銅厚
  7842. int[] b = new int[3];
  7843. int[] y = new int[2];
  7844. int[] tonghouY = new int[2];
  7845. ceju.FanhanShuangcengTonghou_1(gray, out tonghouY, out y, out b);
  7846. int tonghouX = b[1] - 150;
  7847. if (tonghouX <= 0 || tonghouY[0] <= 0)
  7848. {
  7849. ceju.FanhanShuangcengTonghou_1(gray, out tonghouY, out y, out b, 180);
  7850. //if (tonghouY[0] == 0)
  7851. //{//ER(114).JPG
  7852. // //tonghouY[0] = start;
  7853. // for (int i = start - 50/* + 20*/; i < y[1] - 0/*20*/; i++)
  7854. // {
  7855. // sum = result2[i, i + 1, tonghouX - 50, tonghouX + 50].Sum();
  7856. // if ((int)sum > 20/*50*/)
  7857. // {
  7858. // tonghouY[0] = i;
  7859. // break;
  7860. // }
  7861. // }
  7862. //}
  7863. }
  7864. tonghouX = b[1] - 150;
  7865. if (tonghouX <= 0 || tonghouY[0] <= 0)
  7866. {
  7867. ceju.FanhanShuangcengTonghou_2(gray, out tonghouY, out y, out b);
  7868. tonghouX = b[1] - 150;
  7869. }
  7870. if (tonghouX <= 0 || tonghouY[0] <= 0) return;
  7871. tonghou.Set(tonghouY[1] - tonghouY[0], tonghouX + border, tonghouY[0] + upper, tonghouX + border, tonghouY[1] + upper);
  7872. //防焊厚度
  7873. int fanghanhouduX = b[1] - 150;
  7874. int[] fanghanhouduY = new int[2];
  7875. //ceju.Fanghanhoudu4(gray, y, b, tonghouY, out fanghanhouduY);
  7876. fanghanhouduY[0] = y[0] + 20;// tonghouY[0];
  7877. int minGray = 300 * 255;
  7878. ceju.FanghanhouduForShuangmianTonghou_2(gray, y, fanghanhouduX, tonghouY, out fanghanhouduY[1], out minGray, true);
  7879. fanghanhoudu.Set(fanghanhouduY[1] - fanghanhouduY[0], fanghanhouduX + border, fanghanhouduY[0] + upper, fanghanhouduX + border, fanghanhouduY[1] + upper);
  7880. //LPI厚度
  7881. int LPIHouduX = b[1] + 100;
  7882. int[] LPIHouduY = new int[2];
  7883. //ceju.FanghanLPI2(gray, tonghouY, b, fanghanhouduY, out LPIHouduY);
  7884. LPIHouduY[0] = tonghouY[1];
  7885. ceju.FanghanLPIForShuangmianTong(gray, tonghouY, b, fanghanhouduY, out LPIHouduY);
  7886. ceju.FanghanhouduForShuangmianTonghou_2(gray, y, LPIHouduX/*fanghanhouduX*/, tonghouY, out LPIHouduY[1], out minGray, false);
  7887. LPIhoudu.Set(LPIHouduY[1] - LPIHouduY[0], LPIHouduX + border, LPIHouduY[0] + upper, LPIHouduX + border, LPIHouduY[1] + upper);
  7888. //offset
  7889. int[] offsetX = new int[2];
  7890. int offsetY = LPIHouduY[1] + 15;//tonghouY[0] - 50;
  7891. offsetX[1] = b[2];
  7892. offsetX[0] = LPIHouduX + 30;// fanghanhouduX;
  7893. int loophouduY = LPIHouduY[1];
  7894. int loophouduX = LPIHouduX + 30;
  7895. int loopminGray = minGray;
  7896. int houduY = loophouduY;
  7897. Console.WriteLine("minGray:" + minGray + ", houduX:" + loophouduX + " Y:" + loophouduY);
  7898. int colStart = 50;//<-125 loophouduX - (b[1] + 5);
  7899. ceju.FanghanOffsetForShuangmianTong(gray, tonghouY, b, fanghanhouduY, colStart, out offsetX[0]);//debug ER(14).JPG!!!!
  7900. int offsetX_00 = offsetX[0];///////////////////////////////////////////////////////////////////////////
  7901. bool accLeftMargin = false;
  7902. ceju.FanghanOffsetForShuangmianTong_Acc(gray, tonghouY, b, fanghanhouduY, offsetY, offsetX_00, out offsetX[0]);
  7903. if (offsetX_00 - offsetX[0] > 0 && offsetX_00 - offsetX[0] < 10)
  7904. {
  7905. accLeftMargin = true;
  7906. }
  7907. if (offsetX_00 - offsetX[0] < 0 && offsetX_00 - offsetX[0] > -20/*ER(14).JPG*/) offsetX[0] = offsetX_00;
  7908. else offsetX_00 = offsetX[0];
  7909. Console.WriteLine("offsetX:" + offsetX_00);
  7910. int leftDown = 0;//前提假设,按照左下边框测量
  7911. int offsetX_000 = offsetX[0];
  7912. int offsetX_temp = offsetX_00;
  7913. int offsetX_Left = offsetX_00;
  7914. int upperMaxTimes00 = 1;// 0;
  7915. for (int j = offsetY; j < LPIHouduY[0]; j++)
  7916. {
  7917. ceju.FanghanOffsetForShuangmianTong_Acc(gray, tonghouY, b, fanghanhouduY, j, offsetX_00, out offsetX_temp);
  7918. Console.WriteLine("offsetX_temp:" + offsetX_temp);
  7919. if (offsetX_temp - offsetX_00 < 0) leftDown++;
  7920. if (offsetX_temp - offsetX_00 > 5 && offsetX_temp - offsetX_00 < 20 && upperMaxTimes00++ < 1 ||
  7921. Math.Abs(offsetX_temp - offsetX_00) < 5/*10*//*5*/)
  7922. {
  7923. offsetX_00 = offsetX_temp;
  7924. if (offsetX[0] < offsetX_temp) offsetX[0] = offsetX_temp;
  7925. if (offsetX_Left > offsetX_temp) offsetX_Left = offsetX_temp;
  7926. }
  7927. }
  7928. if (leftDown < 10/* <- ER(96).JPG 5*//*10*/) offsetX[0] = offsetX_000 - 5;
  7929. //纠正191情况
  7930. if (true)
  7931. {
  7932. }
  7933. //ceju.FanghanOffset6(gray, tonghouY, b, fanghanhouduY, out offsetX);
  7934. offsetY = LPIHouduY[1] + 15;// tonghouY[0] - 50;
  7935. offset.Set(offsetX[1] - offsetX[0], offsetX[0] + border, offsetY + upper, offsetX[1] + border, offsetY + upper);
  7936. int upperMaxTimes = 0;
  7937. for (int j = offsetY; j < tonghouY[1]/*LPIHouduY[0]*/; j++)
  7938. {
  7939. ceju.FanghanOffsetForShuangmianTong_Acc(gray, tonghouY, b, fanghanhouduY, j, offsetX_00, out offsetX_temp);
  7940. Console.WriteLine("undercutX_temp:" + offsetX_temp);
  7941. if (/*Math.Abs(*/offsetX_temp - offsetX_Left/*)*/ > -25 && offsetX_temp - offsetX_Left < -10 && upperMaxTimes++ < 1 ||
  7942. Math.Abs(offsetX_temp - offsetX_00) < 11/*10*//*20*//*10*//*15*//*10*//*5*/)
  7943. {
  7944. if (offsetX_temp - offsetX_00 < -15)//0)
  7945. offsetX_00 = offsetX_temp;
  7946. else
  7947. offsetX_00 -= 1;
  7948. //if (offsetX[0] < offsetX_temp) offsetX[0] = offsetX_temp;
  7949. if (offsetX_Left > offsetX_temp)
  7950. offsetX_Left = offsetX_temp;
  7951. }
  7952. }
  7953. if (offsetX_000 - offsetX_Left < 5) offsetX_Left = Math.Min(offsetX[0], offsetX_000) - 15;
  7954. //undercut
  7955. int[] undercutX = new int[2] { offsetX_Left, offsetX[0] };
  7956. int undercutY = tonghouY[1] + 20;
  7957. //ceju.FanghanUndercut6_3(gray, tonghouY, b, offsetX, LPIHouduY, out undercutX[0]);
  7958. //undercutX[1] = offsetX[0];
  7959. //if (undercutX[1] - undercutX[0] > 100) undercutX[0] = undercutX[1] - 34;
  7960. undercut.Set(undercutX[1] - undercutX[0], undercutX[0] + border, undercutY + upper, undercutX[1] + border, undercutY + upper);
  7961. //update value
  7962. offset.Set(offsetX[1] - offsetX[0], offsetX[0] + border, offsetY + upper, offsetX[1] + border, offsetY + upper);
  7963. //安全距離
  7964. int anquanjuliY = tonghouY[1] + 50;
  7965. int[] anquanjuliX = { b[1], undercutX[0] };
  7966. anquanjuli.Set(anquanjuliX[1] - anquanjuliX[0], anquanjuliX[0] + border, anquanjuliY + upper, anquanjuliX[1] + border, anquanjuliY + upper);
  7967. #region[释放内存]
  7968. if (gray != null && !gray.IsDisposed)
  7969. {
  7970. gray.Dispose();
  7971. }
  7972. if (result != null && !result.IsDisposed)
  7973. {
  7974. result.Dispose();
  7975. }
  7976. #endregion
  7977. }
  7978. }
  7979. }