{"id":1985,"date":"2018-03-13T14:55:24","date_gmt":"2018-03-13T06:55:24","guid":{"rendered":"http:\/\/www.magicandlove.com\/blog\/?p=1985"},"modified":"2018-03-13T14:57:08","modified_gmt":"2018-03-13T06:57:08","slug":"cvimage-and-pixelflow-in-processing","status":"publish","type":"post","link":"http:\/\/www.magicandlove.com\/blog\/2018\/03\/13\/cvimage-and-pixelflow-in-processing\/","title":{"rendered":"CVImage and PixelFlow in Processing"},"content":{"rendered":"<p>This is a quick demonstration of using the CVImage library, from the book, <a href=\"https:\/\/www.apress.com\/la\/book\/9781484227749\" target=\"_blank\" rel=\"noopener\">Pro Processing for Images and Computer Vision with OpenCV<\/a>, and the <a href=\"https:\/\/github.com\/diwi\/PixelFlow\" target=\"_blank\" rel=\"noopener\">PixelFlow<\/a> library from <a href=\"http:\/\/thomasdiewald.com\/blog\/\" target=\"_blank\" rel=\"noopener\">Thomas Diewald<\/a>.<br \/>\n&nbsp;<br \/>\n<em>Here is the video documentation.<\/em><br \/>\n<iframe loading=\"lazy\" width=\"560\" height=\"315\" src=\"https:\/\/www.youtube.com\/embed\/NEI-cSWaIt8?rel=0\" frameborder=\"0\" allow=\"autoplay; encrypted-media\" allowfullscreen><\/iframe><\/p>\n<p>The full source code is below with one additional class.<\/p>\n<p><em>Main Processing sketch<\/em><\/p>\n<pre lang=\"java\">\r\nimport cvimage.*;\r\nimport processing.video.*;\r\nimport com.thomasdiewald.pixelflow.java.DwPixelFlow;\r\nimport com.thomasdiewald.pixelflow.java.fluid.DwFluid2D;\r\nimport org.opencv.core.*;\r\nimport org.opencv.objdetect.CascadeClassifier;\r\nimport org.opencv.objdetect.Objdetect;\r\n\r\n\/\/ Face detection size\r\nfinal int W = 320, H = 180;\r\nCapture cap;\r\nCVImage img;\r\nCascadeClassifier face;\r\nfloat ratio;\r\nDwFluid2D fluid;\r\nPGraphics2D pg_fluid;\r\nMyFluidData fluidFunc;\r\n\r\nvoid settings() {\r\n  size(1280, 720, P2D);\r\n}\r\n\r\nvoid setup() {\r\n  background(0);\r\n  System.loadLibrary(Core.NATIVE_LIBRARY_NAME);\r\n  println(Core.VERSION);\r\n  cap = new Capture(this, width, height);\r\n  cap.start();\r\n  img = new CVImage(W, H);\r\n  face = new CascadeClassifier(dataPath(\"haarcascade_frontalface_default.xml\"));\r\n  ratio = float(width)\/W;\r\n\r\n  DwPixelFlow context = new DwPixelFlow(this);\r\n  context.print();\r\n  context.printGL();\r\n  fluid = new DwFluid2D(context, width, height, 1);\r\n  fluid.param.dissipation_velocity = 0.60f;\r\n  fluid.param.dissipation_density = 0.99f;\r\n  fluid.param.dissipation_temperature = 1.0f;\r\n  fluid.param.vorticity = 0.001f;\r\n\r\n  fluidFunc = new MyFluidData();\r\n  fluid.addCallback_FluiData(fluidFunc);\r\n  pg_fluid = (PGraphics2D) createGraphics(width, height, P2D);\r\n  pg_fluid.smooth(4);\r\n}\r\n\r\nvoid draw() {\r\n  if (!cap.available()) \r\n    return;\r\n  background(0);\r\n  cap.read();\r\n  cap.updatePixels();\r\n\r\n  img.copy(cap, 0, 0, cap.width, cap.height, \r\n    0, 0, img.width, img.height);\r\n  img.copyTo();\r\n\r\n  Mat grey = img.getGrey();\r\n  MatOfRect faces = new MatOfRect();\r\n\r\n  face.detectMultiScale(grey, faces, 1.15, 3, \r\n    Objdetect.CASCADE_SCALE_IMAGE, \r\n    new Size(60, 60), new Size(200, 200));\r\n  Rect [] facesArr = faces.toArray();\r\n  if (facesArr.length > 0) {\r\n    fluidFunc.findFace(true);\r\n  } else {\r\n    fluidFunc.findFace(false);\r\n  }\r\n  for (Rect r : facesArr) {\r\n    float cx = r.x + r.width\/2.0;\r\n    float cy = r.y + r.height\/2.0;\r\n    fluidFunc.setPos(new PVector(cx*ratio, cy*ratio));\r\n  }\r\n  fluid.update();\r\n  pg_fluid.beginDraw();\r\n  pg_fluid.background(0);\r\n  pg_fluid.image(cap, 0, 0);\r\n  pg_fluid.endDraw();\r\n  fluid.renderFluidTextures(pg_fluid, 0);\r\n  image(pg_fluid, 0, 0);\r\n  pushStyle();\r\n  noStroke();\r\n  fill(0);\r\n  text(nf(round(frameRate), 2, 0), 10, 20);\r\n  popStyle();\r\n  grey.release();\r\n  faces.release();\r\n}\r\n<\/pre>\n<p><em>The class definition of MyFluidData<\/em><\/p>\n<pre lang=\"java\">\r\nprivate class MyFluidData implements DwFluid2D.FluidData {\r\n  float intensity;\r\n  float radius;\r\n  float temperature;\r\n  color c;\r\n  boolean first;\r\n  boolean face;\r\n  PVector pos;\r\n  PVector last;\r\n\r\n  public MyFluidData() {\r\n    super();\r\n    intensity = 1.0f;\r\n    radius = 25.0f;\r\n    temperature = 5.0f;\r\n    c = color(255, 255, 255);\r\n    first = true;\r\n    pos = new PVector(0, 0);\r\n    last = new PVector(0, 0);\r\n    face = false;\r\n  }\r\n\r\n  public void findFace(boolean f) {\r\n    face = f;\r\n  }\r\n\r\n  public void setPos(PVector p) {\r\n    if (first) {\r\n      pos.x = p.x;\r\n      pos.y = p.y;\r\n      last.x = pos.x;\r\n      last.y = pos.y;\r\n      first = false;\r\n    } else {\r\n      last.x = pos.x;\r\n      last.y = pos.y;\r\n      pos.x = p.x;\r\n      pos.y = p.y;\r\n    }\r\n  }\r\n\r\n  @Override\r\n    public void update(DwFluid2D f) {\r\n\r\n    if (face) {\r\n      float px = pos.x;\r\n      float py = height - pos.y;\r\n      float vx = (pos.x - last.x) * 10.0f;\r\n      float vy = (pos.y - last.y) * -10.0f;\r\n      c = color(random(100, 255), random(100, 255), random(50, 100));\r\n      f.addVelocity(px, py, radius, vx, vy);\r\n      f.addDensity (px, py, radius, \r\n        red(c)\/255, green(c)\/255, blue(c)\/255, \r\n        intensity);\r\n      f.addTemperature(px, py, radius, temperature);\r\n    }\r\n  }\r\n}\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>This is a quick demonstration of using the CVImage library, from the book, Pro Processing for Images and Computer Vision with OpenCV, and the PixelFlow library from Thomas Diewald. &nbsp; Here is the video documentation. The full source code is below with one additional class. Main Processing sketch import cvimage.*; import processing.video.*; import com.thomasdiewald.pixelflow.java.DwPixelFlow; import [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[88,79],"tags":[3,158,62],"class_list":["post-1985","post","type-post","status-publish","format-standard","hentry","category-books","category-software-2","tag-opencv","tag-pixelflow","tag-processing-org"],"_links":{"self":[{"href":"http:\/\/www.magicandlove.com\/blog\/wp-json\/wp\/v2\/posts\/1985","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.magicandlove.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.magicandlove.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.magicandlove.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.magicandlove.com\/blog\/wp-json\/wp\/v2\/comments?post=1985"}],"version-history":[{"count":2,"href":"http:\/\/www.magicandlove.com\/blog\/wp-json\/wp\/v2\/posts\/1985\/revisions"}],"predecessor-version":[{"id":1987,"href":"http:\/\/www.magicandlove.com\/blog\/wp-json\/wp\/v2\/posts\/1985\/revisions\/1987"}],"wp:attachment":[{"href":"http:\/\/www.magicandlove.com\/blog\/wp-json\/wp\/v2\/media?parent=1985"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.magicandlove.com\/blog\/wp-json\/wp\/v2\/categories?post=1985"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.magicandlove.com\/blog\/wp-json\/wp\/v2\/tags?post=1985"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}