From 9f3f59a99b2d4f6faf562d5adde0d4774083025d Mon Sep 17 00:00:00 2001 From: HaleySchuhl Date: Fri, 8 Mar 2019 11:35:33 -0600 Subject: [PATCH] add show_grid option to cluster_contours - Added an option to show the grid that is getting used to cluster contours - Added onto unit test - Simplified plotting part of code - Added an example to the documentation - Appended new argument to updating.md - Added the new argument to the multi-plant tutorial --- docs/cluster_contours.md | 8 ++++- .../cluster_contour/show_grid.jpg | Bin 0 -> 39452 bytes docs/multi-plant_tutorial.md | 3 ++ docs/updating.md | 8 +++-- plantcv/plantcv/cluster_contours.py | 34 +++++++----------- tests/tests.py | 2 +- 6 files changed, 29 insertions(+), 26 deletions(-) create mode 100644 docs/img/documentation_images/cluster_contour/show_grid.jpg diff --git a/docs/cluster_contours.md b/docs/cluster_contours.md index 0cf0ef162..55f40be0f 100644 --- a/docs/cluster_contours.md +++ b/docs/cluster_contours.md @@ -2,7 +2,7 @@ This function take a image with multiple contours and clusters them based on user input of rows and columns -**platncv.cluster_contours**(*img, roi_objects, roi_obj_hierarchy, nrow=1,ncol=1*) +**platncv.cluster_contours**(*img, roi_objects, roi_obj_hierarchy, nrow=1,ncol=1, show_grid=False*) **returns** grouped_contour_indexes, contours, hierarchy @@ -12,6 +12,7 @@ This function take a image with multiple contours and clusters them based on use - roi_obj_hierarchy - object hierarchy - nrow - approximate number of rows (default nrow=1) - ncol - approximate number of columns (default ncol=1) + - show_grid - if True then a grid gets displayed in debug mode (default show_grid=False) - **Context:** - Cluster contours based on number of approximate rows and columns - **Example use:** @@ -32,9 +33,14 @@ pcv.params.debug = "print" # clusters them based on user input of rows and columns clusters_i, contours, hierarchy = pcv.cluster_contours(img, roi_objects, roi_obj_hierarchy, 4, 6) +clusters_i, contours, hierarchy = pcv.cluster_contours(img, roi_objects, roi_obj_hierarchy, 4, 6, show_grid=True) ``` **Cluster Contour Image** ![Screenshot](img/documentation_images/cluster_contour/14_clusters.jpg) +**Cluster Contour Image with Grid** + +![Screenshot](img/documentation_images/cluster_contour/show_grid.jpg) + diff --git a/docs/img/documentation_images/cluster_contour/show_grid.jpg b/docs/img/documentation_images/cluster_contour/show_grid.jpg new file mode 100644 index 0000000000000000000000000000000000000000..13044b9b5885cef2020087ad03369066ac058658 GIT binary patch literal 39452 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 z zwVMJ%G>pR=erJsBz!)HP$u-w_W8iOyd==tLKM?qTQi9h}vy@1e=2_;I7!YzIb@ER= zcPkEY)29wEjWV|eqfuP;c+-k_i;HtF?L6v9&dNUOPl^62(dW>7QR4l3Sko@HdG=TOoz2y>zFVw` zzA0p6ZLX@rBZdHuK(D;;zXY=GFv{`w=Js{zO4haQH0^zDe)eY;VTg0XREF12@;_`p zU?}82vX6n>zE}Px`&S=#8m-{#)YsZ^t})--*YfwEd{_9T;XNV^2g1HF@dk~iTJQ2K zwEa@**4i&I+DF+GQYtRzW@CZN5>F)OV0?V|>;C{n8^yo)Jih+`Yp5bHEUXJ&X25oK=DoWh4e3Nb!&62Ud;sXObSU9k-Vi{9Z6PJ1Q19g z74&>Ff{h&84O;i*oL}70$yQSKa!H@L{{Zk#)yM3A;5=n=b$*}r7rq{zmG*p)znWew zWQ-rnj=8VpSHqtd{w;VvMYiz&0EB#P;w=+Pv@P~~Ejw1bw6=%Lc9Hf)6sn84*s;JF zVoBth(Lc05$Mby}ABmnZ+vT~(_VxZU8Xyil{@FjBdmbZGSpF!?aj)I>m8weH+VXDK z(*FQ)mK8Wtj8oY!$o{89GLe&jP=Zg>t~jVBEV#(raDQ6k*!p*}tZKk;(>Vc-5^ z*Z#lt-jTm(ACE2fz9jg(@!ws({{Z9F@iWTp9VPf35N*oL{+cf3nb<3+AmMTbGBfOR z(!87YkP8>=?eQ%WAxDEX@yXBpxKGzL{PrJ@e;qTQ_*mX8$Ri)|Jih+`vp`Hm;q>;%R%2maT(g6bOO4=@%!Vtpxf~u#iO3u z?f3rx96Z(ge6P9LN05DE^nxM*j#%`mp zKGpojf5Slhdcgkxi<9F20Q?@`fARW7`1$eFw&U>|#k;fD`*Qm~`Z~WbsgkSwe~0`N z(4$%Ge@+W(T4>qVA%x8hHW#_5Wj zYq#8wEzS?`x^Y)O;h=s!05S0=#p9p)4&Q(A>fZ&D#x;+Mp42K*^YD=k_Zy<=I{ zozmyzAVDytHB#d(F_!jFmn02eh4LJy4hc3N+O=T9Mg z8=_oD!tOOYmP`Bd4ZYACunZ75i0#9)isV=0Bp(*ODqCw88uhn~{6Q9{bqI=k)YUGQ z=2VT&#d$=V*;gk3oDA_+ExtE=XlU9-@%M@gERw3R)^7<5xwr?-;B#M{)5+z8hdvgk zESj@+*57&U{dL*dekbnUp`qyB7P1q=1WLBb;T8lDgpJ4wim8Ex3J0+7Uzolv_<>>Y zx5Qp4@a~jMFzQpLy=xL+k23EOP6p%DynFG`ZZ-0(-xmHV-$#qz8Tf|aVSm=@w@=^w zsZDVg*Z11Y{{U>&?j^ps5s)RhcA3D-ak%wzs#GJP{;p9Y`plPft->mi{a8Mv(AY={m*zlr1jf9lg}CAtfA=RTvDC z0Y2bY?LSG*O#c9ku{oMv&B;?%__n77zMZ=sFAY^xu!@|O?SIVvgZw{sZ{hQ!UN_@+ zAmanK<6T|dv~t-pfH!9=o&Y~l+P|Lre~TX!?KcZg8F+#p`sb=$FQ=q}tV!{k;{l9= z)(f%jl{{RH_D&p-crTu-!?!=I^E~K{7Gk^)t6!el~hDIkJ z%D)H?#t(~ZPVXCdjP&cPU7p|d){uN&__Cwr@vn%7Bc`i&>;C{guO#>XG?F>1g1S1ozo$Mmla@gIo%Lwn*KQug;$y|}ozy||WHWw?>#l1Gt? oGcjUWn4FS%Cb7S^wU7D!x&Hva&;B*{KiQw&{6FBFUfan3+0g>IDF6Tf literal 0 HcmV?d00001 diff --git a/docs/multi-plant_tutorial.md b/docs/multi-plant_tutorial.md index e355e3fed..d2c34b197 100644 --- a/docs/multi-plant_tutorial.md +++ b/docs/multi-plant_tutorial.md @@ -325,6 +325,8 @@ roi_objects, roi_obj_hierarchy, kept_mask, obj_area = pcv.roi_objects(img1, 'par # roi_obj_hierarchy = object hierarchy # nrow = number of rows to cluster (this should be the approximate number of desired rows in the entire image even if there isn't a literal row of plants) # ncol = number of columns to cluster (this should be the approximate number of desired columns in the entire image even if there isn't a literal row of plants) +# show_grid = if True then a grid gets displayed in debug mode (default show_grid=False) + clusters_i, contours, hierarchies = pcv.cluster_contours(img1, roi_objects, roi_obj_hierarchy, 4, 6) ``` @@ -561,6 +563,7 @@ def main(): # roi_obj_hierarchy = object hierarchy # nrow = number of rows to cluster (this should be the approximate number of desired rows in the entire image even if there isn't a literal row of plants) # ncol = number of columns to cluster (this should be the approximate number of desired columns in the entire image even if there isn't a literal row of plants) + # show_grid = if True then a grid gets displayed in debug mode (default show_grid=False) clusters_i, contours, hierarchies = pcv.cluster_contours(img1, roi_objects, roi_obj_hierarchy, 4, 6) diff --git a/docs/updating.md b/docs/updating.md index 557b6bf6a..c618460d9 100644 --- a/docs/updating.md +++ b/docs/updating.md @@ -186,7 +186,7 @@ pages for more details on the input and output variable types. * pre v3.0dev2: device, cropped = **plantcv.auto_crop**(*device, img, objects, padding_x=0, padding_y=0, color='black', debug=None*) * post v3.0dev2: cropped = **plantcv.auto_crop**(*img, objects, padding_x=0, padding_y=0, color='black'*) -* post v3.2: cropped = **plantcv.auto_crop**(*img, obj, padding_x=0, padding_y=0, color='black*) +* post v3.2: cropped = **plantcv.auto_crop**(*img, obj, padding_x=0, padding_y=0, color='black'*) #### plantcv.background_subtraction @@ -202,7 +202,7 @@ pages for more details on the input and output variable types. #### plantcv.canny_edge_detect ** pre v3.2: NA -** post v3.2: bin_img = **plantcv.canny_edge_detect**(*img, mask = None, sigma=1.0, low_thresh=None, high_thresh=None, thickness=1, mask_color=None, use_quantiles=False*) +** post v3.2: bin_img = **plantcv.canny_edge_detect**(*img, mask=None, sigma=1.0, low_thresh=None, high_thresh=None, thickness=1, mask_color=None, use_quantiles=False*) #### plantcv.cluster_contour_splitimg @@ -213,6 +213,7 @@ pages for more details on the input and output variable types. * pre v3.0dev2: device, grouped_contour_indexes, contours, roi_obj_hierarchy = **plantcv.cluster_contours**(*device, img, roi_objects,roi_obj_hierarchy, nrow=1, ncol=1, debug=None*) * post v3.0dev2: grouped_contour_indexes, contours, roi_obj_hierarchy = **plantcv.cluster_contours**(*img, roi_objects, roi_obj_hierarchy, nrow=1, ncol=1*) +* post v3.2: grouped_contour_indexes, contours, roi_obj_hierarchy = **plantcv.cluster_contours**(*img, roi_objects, roi_object_hierarchy, nrow=1, ncol=1, show_grid=False*) #### plantcv.color_palette @@ -360,6 +361,7 @@ post v3.0: new_img = **plantcv.image_subtract**(*gray_img1, gray_img2*) * pre v3.0dev2: bins, hist = **plantcv.plot_hist**(*img, name=False*) * post v3.0dev2: bins, hist = **plantcv.plot_hist**(*img, name=False*) +* post v3.2: header, hist_data, hist_figure = **pcv.plot_hist**(*gray_img, mask=None, bins=256*) #### plantcv.plot_image @@ -538,7 +540,7 @@ post v3.0: new_img = **plantcv.image_subtract**(*gray_img1, gray_img2*) #### plantcv.transform.find_color_card * pre v3.0: NA -* post v3.0: df, start_coord, spacing = **plantcv.transofrm.find_color_card**(*rgb_img, threshold='adaptgauss', threshvalue=125, blurry=False, background='dark'*) +* post v3.0: df, start_coord, spacing = **plantcv.transform.find_color_card**(*rgb_img, threshold='adaptgauss', threshvalue=125, blurry=False, background='dark'*) #### plantcv.transform.get_color_matrix diff --git a/plantcv/plantcv/cluster_contours.py b/plantcv/plantcv/cluster_contours.py index 4c221f2d3..a02ad6772 100755 --- a/plantcv/plantcv/cluster_contours.py +++ b/plantcv/plantcv/cluster_contours.py @@ -7,7 +7,7 @@ from plantcv.plantcv import params -def cluster_contours(img, roi_objects, roi_obj_hierarchy, nrow=1, ncol=1): +def cluster_contours(img, roi_objects, roi_obj_hierarchy, nrow=1, ncol=1, show_grid=False): """ This function take a image with multiple contours and clusters them based on user input of rows and columns @@ -20,8 +20,7 @@ def cluster_contours(img, roi_objects, roi_obj_hierarchy, nrow=1, ncol=1): in the entire image (even if there isn't a literal row of plants) ncol = number of columns to cluster (this should be the approximate number of desired columns in the entire image (even if there isn't a literal row of plants) - file = output of filename from read_image function - filenames = input txt file with list of filenames in order from top to bottom left to right + show_grid = if True then the grid will get plot to show how plants are being clustered Returns: grouped_contour_indexes = contours grouped @@ -31,6 +30,7 @@ def cluster_contours(img, roi_objects, roi_obj_hierarchy, nrow=1, ncol=1): :param roi_objects: list :param nrow: int :param ncol: int + :param show_grid: bool :return grouped_contour_indexes: list :return contours: list :return roi_obj_hierarchy: list @@ -123,7 +123,7 @@ def digitize(a, step): # Debug image is rainbow printed contours - if params.debug == 'print': + if params.debug is not None: if len(np.shape(img)) == 3: img_copy = np.copy(img) else: @@ -137,22 +137,14 @@ def digitize(a, step): pass else: cv2.drawContours(img_copy, roi_objects, a, rand_color[i], -1, hierarchy=roi_obj_hierarchy) - print_image(img_copy, os.path.join(params.debug_outdir, str(params.device) + '_clusters.png')) - - elif params.debug == 'plot': - if len(np.shape(img)) == 3: - img_copy = np.copy(img) - else: - iy, ix = np.shape(img) - img_copy = np.zeros((iy, ix, 3), dtype=np.uint8) - - rand_color = color_palette(len(coordlist)) - for i, x in enumerate(coordlist): - for a in x: - if roi_obj_hierarchy[0][a][3] > -1: - pass - else: - cv2.drawContours(img_copy, roi_objects, a, rand_color[i], -1, hierarchy=roi_obj_hierarchy) - plot_image(img_copy) + if show_grid: + for y in rbreaks: + cv2.line(img_copy, (0, y), (ix, y), (255, 0, 0), params.line_thickness) + for x in cbreaks: + cv2.line(img_copy, (x, 0), (x, iy), (255, 0, 0), params.line_thickness) + if params.debug=='print': + print_image(img_copy, os.path.join(params.debug_outdir, str(params.device) + '_clusters.png')) + elif params.debug=='plot': + plot_image(img_copy) return grouped_contour_indexes, contours, roi_obj_hierarchy diff --git a/tests/tests.py b/tests/tests.py index 617302cba..54a7a96a2 100755 --- a/tests/tests.py +++ b/tests/tests.py @@ -637,7 +637,7 @@ def test_plantcv_cluster_contours(): # Test with debug = "print" pcv.params.debug = "print" _ = pcv.cluster_contours(img=img1, roi_objects=objs, roi_obj_hierarchy=obj_hierarchy, nrow=4, ncol=6) - _ = pcv.cluster_contours(img=img1, roi_objects=objs, roi_obj_hierarchy=obj_hierarchy) + _ = pcv.cluster_contours(img=img1, roi_objects=objs, roi_obj_hierarchy=obj_hierarchy, show_grid=True) # Test with debug = "plot" pcv.params.debug = "plot" _ = pcv.cluster_contours(img=img1, roi_objects=objs, roi_obj_hierarchy=obj_hierarchy, nrow=4, ncol=6)