Package: cvlayer
cvlayerOpenCV Layer HelperOverviewWhen performing image-based machine learning/inference, many situations arise that require pre-/post-processing appropriate for the domain environment.A commonly used library today isOpenCV.Image processing withOpenCVrequires insight into the image and the domain.However, gaining these insights often requires doing something far from the essence. (Visualization, parameter modification, library conflicts, assertions, etc...)Here are some problems that occurred to me:...Features...InstallationInstallcvlayer:pipinstallcvlayerInstallcvlayerwithopencv-python:pipinstallcvlayer[opencv]Installcvlayerwithopencv-python-headless:pipinstallcvlayer[headless]UsageCvLayerJust inheritcvlayer.CvLayer.fromcvlayerimportCvLayerclassYourApp(CvLayer):deffunc(self,image):self.cvl_cvt_color_bgr2hsv(image)CvWindowJust inheritcvlayer.CvWindow.fromcvlayerimportCvWindowfromnumpy.typingimportNDArrayclassYourApp(CvWindow):defon_frame(self,image:NDArray)->NDArray:# TODO: Implement image processing logic ...returnimageYourApp("/path/to/video/file.mp4").run()ExampleThe following sample is aPerspective Transformexample:fromsysimportargv,stderrfromsysimportexitassys_exitfromtypingimportList,OptionalfromcvlayerimportCvLayer,CvMixin,CvWindowfromcvlayer.typingimportPointIfromcvlayer.palette.basicimportREDfromnumpy.typingimportNDArrayclassYourApp(CvWindow,CvMixin,CvLayer):_points:List[PointI]def__init__(self,source:str,destination:Optional[str]=None):super().__init__(source,destination)left_top=930,2750left_bottom=846,3098right_top=1091,2750right_bottom=1361,3098self._points=[left_top,left_bottom,right_top,right_bottom]self._scale=2,4defon_frame(self,image:NDArray)->NDArray:withself.layer("select-roi")aslayer:self.roi=layer.param("roi").build_select_roi().valuelayer.frame=layer.prev_framewithself.layer("perspective-points")aslayer:points=layer.param("pp").build_select_points(self._points).valuecanvas=layer.prev_frame.copy()forpinpoints:self.cvl_draw_point(canvas,p,color=RED)layer.frame=canvaswithself.layer("perspective-transform")aslayer:sw=layer.param("scale-width").build_uint(self._scale[0]).valuesh=layer.param("scale-height").build_uint(self._scale[1]).valuexs=list(map(lambdapoint:point[0],self._points))ys=list(map(lambdapoint:point[1],self._points))x1,x2=min(xs),max(xs)y1,y2=min(ys),max(ys)width,height=abs(x2-x1)*sw,abs(y2-y1)*shroi=0,0,width,heightm=self.cvl_get_perspective_transform_with_quadrilateral(left_top=points[0],left_bottom=points[1],right_top=points[2],right_bottom=points[3],destination_roi=roi,)layer.frame=self.cvl_warp_perspective(image,m,(width,height))withself.layer("hsv")aslayer:layer.frame=hsv=self.cvl_cvt_color_bgr2hsv(layer.prev_frame)withself.layer("hsv-h")aslayer:layer.frame=h=hsv[:,:,0]withself.layer("hsv-s")aslayer:layer.frame=s=hsv[:,:,1]withself.layer("hsv-v")aslayer:layer.frame=v=hsv[:,:,2]asserthisnotNoneassertsisnotNoneassertvisnotNoneself.cvm_gaussian_blur("v-blur",(3,19),0.0,7.0)self.cvm_threshold_binary("v-thresh",230)returnself.last_framedeftest_main(*args)->None:source=args[1]destination=args[2]iflen(args)>=3elseNonetry:app=YourApp(source,destination)app.run()exceptExceptionase:print(e,file=stderr)sys_exit(1)else:sys_exit(0)if__name__=="__main__":test_main(*argv)LicenseSee theLICENSEfile for details. In summary,cvlayeris licensed under theMIT license.