当前位置: 首页 > news >正文

成都h5模板建站wordpress食谱

成都h5模板建站,wordpress食谱,铜山网站开发,网站集约化建设的通知本文作者为 360 奇舞团前端开发工程师 随着AI的火热发展#xff0c;涌现了一些AI模特换装的前端工具#xff08;比如weshop网站#xff09;#xff0c;他们是怎么实现的呢#xff1f;使用了什么技术呢#xff1f;下文我们就来探索一下其实现原理。 总体的实现流程如下涌现了一些AI模特换装的前端工具比如weshop网站他们是怎么实现的呢使用了什么技术呢下文我们就来探索一下其实现原理。 总体的实现流程如下我们将下图中的这个模特的图片使用Segment Anything Model在后端分割图层然后将分割后的图层mask信息返回给前端处理。在前端中选择需要保留的图层信息如下图中的模特的衣服图层然后将选中的图层信息交给后端中的Stable Diffusion处理。后端使用原始图片结合选中的图层蒙版图片结合图生图的功能可以实现weshop等网站的模特换衣等功能。 本文先简单介绍一下使用SAM智能图层分割然后主要介绍一下在前端中怎么对分割后的图层进行选择的处理流程。 使用SAM识别图层 首先我们需要对图层进行分割在SAM出来之前我们需要使用PS将模特的衣服选取出来然后倒出衣服的模板然后再使用其他工具进行替换。但是现在有了SAM后我们可以对图片中的事物进去只能区分获取各种物品的图层。 Segment Anything ModelSAM是一种尖端的图像分割模型可以进行快速分割为图像分析任务提供无与伦比的多功能性。SAM 的先进设计使其能够在无需先验知识的情况下适应新的图像分布和任务这一功能称为零样本传输。SAM 使任何人都可以在不依赖标记数据的情况下为其数据创建分段掩码。 要深入了解 Segment Anything 模型和 SA-1B 数据集请访问Segment Anything 网站https://segment-anything.com/并查看研究论文Segment Anythinghttps://arxiv.org/abs/2304.02643。 我们使用SAM进行图像分割将一个图片中的物体分割成不同的部分。 def mask2rle(img):img: numpy array, 1 - mask, 0 - backgroundReturns run length as string formatedpixels  img.T.flatten()pixels  np.concatenate([[0], pixels, [0]])runs  np.where(pixels[1:] ! pixels[:-1])[0]  1runs[1::2] - runs[::2]return  .join(str(x) for x in runs)def trans_anns(anns):if len(anns)  0:returnsorted_anns  sorted(anns, key(lambda x: x[area]), reverseFalse)list  []index  0# 对每个注释进行处理for ann in sorted_anns:bool_array  ann[segmentation]# 将boolean类型的数组转换为int类型int_array  bool_array.astype(int)# 转化为RLE格式rle  mask2rle(int_array)list.append({index: index, mask: rle})index  1return listimage  cv2.imread(your image path)import sys sys.path.append(your segment-anything link path) from segment_anything import sam_model_registry, SamAutomaticMaskGenerator, SamPredictor# sam 模型路径 sam_checkpoint  your sam model path # 根据下载的模型设置对应的类型 model_type  vit_h# device  cuda sam  sam_model_registry[model_type](checkpointsam_checkpoint) # sam.to(devicedevice) mask_generator  SamAutomaticMaskGenerator(sam) masks  mask_generator.generate(image) # 处理sam返回的图层信息 mask_list  trans_anns(masks)mask_obj  {height: image.shape[0],width: image.shape[1],mask_list: mask_list }import json print(json.dumps(mask_obj)) 运行以上python代码之前需要配置sam的python环境具体的配置描述请查看sam的官方描述。 我们通过以上代码将我们提供的图片通过SAM处理后返回图层分割数据。在trans_anns方法中将图层按照area从小到大的顺序排序。遍历各个图层将boolean类型的数组转换为 0 1 int类型然后对二维numpy array类型的0 1二进制mask图像转换为RLE格式。 RLE是一种简单的无损数据压缩算法通常用于表示连续的相同值的序列。RLE编码的字符串通常用于在图像分割等任务中存储和传输二进制掩码信息以便更有效地表示图像中的目标区域。并且方便数据压缩和传输。我们参照的这种编解码方式。也可以使用coco RLE的编解码方式。 将编码后的各图层信息存储到list中就可以通过接口传输给前端处理了。 前端选择图层 下面这些是本文的重点在前端将刚才解析后的mask_list信息展示并可以通过交互选取需要保留的模版并生成最终合并选取的mask生成一个需要保留的服装模版。 body中的基本组件为 div idlayer-box style width: 500px; height: 500px;position: relativeimg stylewidth: 100%; height: 100%; position: absolute srchttps://p0.ssl.qhimg.com/t01989f0d446bed3e58.jpg //divdiv idsave clicksave stylemargin-top: 20px;margin-right: 20px; margin-left: 20px;保存/divcanvas idmergedCanvas styleborder:1px solid #000;/canvas id为layer-box的div组件作为各个mask的父组件用于查找和管理各个mask的隐藏和展示。其子组件中的第一个标签是展示原始的模特图片的。 id为save的组件在点击时可以处理保存选中的各个mask为一个新的mask图片用于处理图片合成。 id为mergedCanvas的canvas是进行图片合成和展示合成后的图片的。 解析SAM处理后的mask_list信息 /*** rle格式图片信息转换为mask信息*/function rle2mask(mask_rle, shape  [500, 500]) {/*mask_rle: run-length as string formatted (start length)shape: [width, height] of array to returnReturns an array, 1 - mask, 0 - background*/const s  mask_rle.split( );let starts  s.filter((_, index)  index % 2  0).map(Number);const lengths  s.filter((_, index)  index % 2 ! 0).map(Number);starts  starts.map(start  start - 1);const ends  starts.map((start, index)  start  lengths[index]);const img  new Array(shape[0] * shape[1]).fill(0);for (let i  0; i  starts.length; i) {for (let j  starts[i]; j  ends[i]; j) {img[j]  1;}}// return transposeArray(img, shape);const transposed  new Array(shape[1]).fill(0).map(()  new Array(shape[0]).fill(0));for (let i  0; i  shape[0]; i) {for (let j  0; j  shape[1]; j) {transposed[j][i]  img[i * shape[1]  j];}}return transposed;}/*** 转换mask图片信息并设置mask的填充颜色*/function transformMaskImage(item, _width, _height) {let canvas  document.createElement(canvas);let canvasContext  canvas.getContext(2d);canvas.width  _width;canvas.height  _height;let rgbaData  rle2mask(item.mask || , [_width, _height])for (let y  0; y  rgbaData.length; y) {let row  rgbaData[y];for (let x  0; x  row.length; x) {let dot  rgbaData[y][x];if (1  dot  canvasContext) {// 值为1的点填充颜色(canvasContext.fillStyle  #4169eb), canvasContext.fillRect(x, y, 1, 1);}}}// canvas当前层的图片base64格式// matrix上边生成的二维数组return { imageData: canvas.toDataURL(image/png), matrix: rgbaData };}// 使用sam处理后的图层信息rle编码后的由于篇幅限制已省略const res  { height: 500, width: 500, mask_list: [{ index: 0, mask: 109864 3 110361 7 110860 9 111359 10 111859 10 112359 10 112860 9 113360 10 113860 10 114360 10 114860 10 115360 10 115861 8 }, { index: 1, mask: 121910 2 122409 4 122908 6 123408 7 123907 8 124407 9 124907 9 125406 11 125905 12 126404 13 126905 12 127405 12 127906 12 128406 12 128907 11 129407 10 129908 8 130408 4 },......] }layers  res.mask_list.map((item) transformMaskImage(item, res.width, res.height)); res是sam处理后返回的图层信息由于篇幅限制已省略详情请看demohttps://github.com/yuhao1128/AI-model-mask-select-demo/blob/main/index.html中的数据。遍历mask_list使用canvas保存各个mask的信息。由于前面sam处理后的mask_list是经过压缩编码的所以在rle2mask方法中对rle编码后的数据解码为 0/1二维数组的格式。rle2mask中的解码方式请参考这种解码https://www.kaggle.com/code/pestipeti/decoding-rle-masks方式。 然后遍历二维数组将值为1的点填充颜色此处是填充的rgba为#4169eb的颜色可以根据需要自己修改为其他的颜色。此处填充的颜色会在下文中鼠标移动到mask上面时在mask展示的时候呈现此颜色。 最后在layers中存储各个mask的base64格式的图片信息和二维数组信息。 将各个mask添加到图层 const box  document.querySelector(#layer-box);const baseStyle  width:100%;height:100%;position: absolute;;//将各个mask添加为layer-box的子组件并隐藏mask的展示layers.forEach((ele)  {const image  document.createElement(img);image.src  ele.imageData;image.style  ${baseStyle}opacity:0;image.className  layer;box.append(image);}); 将各个mask添加的图片添加为layer-box组件的子组件并且设置opacity为0先隐藏这些mask的展示在下文会监听鼠标的位置通过设置mask的opacity属性来展示mask。 监听鼠标的位置和点击 // 鼠标移入mask组件的区域时展示maskbox.addEventListener(mousemove, (e)  {const { clientX, clientY }  e;const X  box.getBoundingClientRect().left  document.body.scrollLeft;const Y  box.getBoundingClientRect().top  document.body.scrollTop;const x  parseInt(res.width * (clientX - X) / box.getBoundingClientRect().width)const y  parseInt(res.height * (clientY - Y) / box.getBoundingClientRect().height)const allLayers  box.querySelectorAll(.layer);const index  layers.findIndex((item)  item.matrix?.[y]?.[x]);allLayers.forEach((ele, i)  {if (i  index) {ele.style  ${baseStyle}opacity:0.7;} else {// 已经选中的不需要隐藏if (selectedIndexList.indexOf(i)  -1) {ele.style  ${baseStyle}opacity:0;}}});});// 鼠标移出mask组件的区域时隐藏maskbox.addEventListener(mouseout, (e)  {console.log(mouseout selectedIndexList, selectedIndexList);const allLayers  box.querySelectorAll(.layer);allLayers.forEach((ele, i)  {// 只有选中的才会展示if (selectedIndexList.indexOf(i)  -1) {ele.style  ${baseStyle}opacity:0.7;} else {ele.style  ${baseStyle}opacity:0;}});});// 用户点击时保存用户选中的mask的indexbox.addEventListener(mousedown, (e)  {const { clientX, clientY }  e;const X  box.getBoundingClientRect().left  document.body.scrollLeft;const Y  box.getBoundingClientRect().top  document.body.scrollTop;const x  parseInt(res.width * (clientX - X) / box.getBoundingClientRect().width)const y  parseInt(res.height * (clientY - Y) / box.getBoundingClientRect().height)const index  layers.findIndex((item)  item.matrix?.[y]?.[x]);if (selectedIndexList.indexOf(index)  -1) {//保存点击选中的元素indexselectedIndexList.push(index)}}); box就是上文的layer-box是各个mask的父组件。layer-box监听鼠标的move事件和click事件当move到对应的mask上时将mask展示移除mask时隐藏mask。mask在list中是从小到大的顺序所以遍历匹配mask时会优先匹配面积小的组件方便灵活选择。当点击mask的位置时保存mask在list中的index到selectedIndexList中方便后续导出保存选择并高亮展示选中的mask。 选中的mask合成图片 // 存储各个图层图片信息let layers  []// 选择layer的indexconst selectedIndexList  []// 点击保存document.getElementById(save).onclick  function () {const images  [];selectedIndexList.forEach(index  {images.push(layers[index].imageData)})drawing(images)}/*** 图片合成*/function drawing(images) {const canvas  document.getElementById(mergedCanvas);canvas.width  500;  // 设置canvas宽canvas.height  500; // 设置canvas高const ctx  canvas.getContext(2d);let loadedImages  0;images.forEach(function (src) {const img  new Image();img.src  src;img.onload  function () {loadedImages;// 绘制每张图片到 canvas 上ctx.drawImage(img, 0, 0);// 如果所有图片都加载完成保存合并后的图片if (loadedImages  images.length) {// 获取图片的像素数据const imageData  ctx.getImageData(0, 0, img.width, img.height);const data  imageData.data;// 转换为黑白效果for (let i  0; i  data.length; i  4) {// 将 R、G、B 设置为0data[i]  0;data[i  1]  0;data[i  2]  0;}// 将修改后的数据放回 canvasctx.putImageData(imageData, 0, 0);// 导出为 base64 图片const mergedImageBase64  canvas.toDataURL(image/png);// 如果需要你可以将mergedImageBase64图片用于其他操作比如发送到服务器}};});} 当选择完成后可以点击“保存”按钮将选择的mask使用canvas生成一个合并后的图片。此处已将合成后的图片转换为黑白蒙版照片之后可以使用这个合并后的图片进行后续的处理。 根据选中的图层点击保存后生成的模板如下图所示。 预览效果https://yuhao1128.github.io/AI-model-mask-select-demo/、代码详情https://github.com/yuhao1128/AI-model-mask-select-demo/blob/main/index.html 使用Stable Diffusion进行后续的处理 由于篇幅的限制并且这部分网络上以及有很多的介绍资料就不再本文中进行介绍了可以参考这篇文章https://www.uisdc.com/stable-diffusion-24的介绍尝试体验一下在本地中使用Stable Diffusion的图生图的「重绘蒙版」来进行模特的重新绘制。 也可以在后端部署Stable Diffusion服务中处理模特换装。将前面的模特原图以及生成的蒙版图片以及其他的SD的图生图功能的参数传给后端的SD服务处理。 除了模特换装的功能上面的流程还可以应用到物品换背景的功能中。其他的一些智能抠图智能替换的功能都可以扩展上面的处理流程来实现。 参考链接 https://github.com/facebookresearch/segment-anything https://juejin.cn/post/7248903246970503223#heading-2 https://www.uisdc.com/stable-diffusion-24 - END - 关于奇舞团 奇舞团是 360 集团最大的大前端团队代表集团参与 W3C 和 ECMA 会员TC39工作。奇舞团非常重视人才培养有工程师、讲师、翻译官、业务接口人、团队 Leader 等多种发展方向供员工选择并辅以提供相应的技术力、专业力、通用力、领导力等培训课程。奇舞团以开放和求贤的心态欢迎各种优秀人才关注和加入奇舞团。
文章转载自:
http://www.morning.lgmty.cn.gov.cn.lgmty.cn
http://www.morning.pdtjj.cn.gov.cn.pdtjj.cn
http://www.morning.rnds.cn.gov.cn.rnds.cn
http://www.morning.wmsgt.cn.gov.cn.wmsgt.cn
http://www.morning.rtzd.cn.gov.cn.rtzd.cn
http://www.morning.gxtbn.cn.gov.cn.gxtbn.cn
http://www.morning.qwmpn.cn.gov.cn.qwmpn.cn
http://www.morning.qbfwb.cn.gov.cn.qbfwb.cn
http://www.morning.zsfooo.com.gov.cn.zsfooo.com
http://www.morning.thrgp.cn.gov.cn.thrgp.cn
http://www.morning.nlqmp.cn.gov.cn.nlqmp.cn
http://www.morning.qxlxs.cn.gov.cn.qxlxs.cn
http://www.morning.pgrsf.cn.gov.cn.pgrsf.cn
http://www.morning.jrrqs.cn.gov.cn.jrrqs.cn
http://www.morning.qxgmp.cn.gov.cn.qxgmp.cn
http://www.morning.czqqy.cn.gov.cn.czqqy.cn
http://www.morning.gnfkl.cn.gov.cn.gnfkl.cn
http://www.morning.qqtzn.cn.gov.cn.qqtzn.cn
http://www.morning.znkls.cn.gov.cn.znkls.cn
http://www.morning.wkgyz.cn.gov.cn.wkgyz.cn
http://www.morning.ljxxl.cn.gov.cn.ljxxl.cn
http://www.morning.kxrhj.cn.gov.cn.kxrhj.cn
http://www.morning.gtmgl.cn.gov.cn.gtmgl.cn
http://www.morning.dygsz.cn.gov.cn.dygsz.cn
http://www.morning.rmqmc.cn.gov.cn.rmqmc.cn
http://www.morning.rntyn.cn.gov.cn.rntyn.cn
http://www.morning.hhskr.cn.gov.cn.hhskr.cn
http://www.morning.pzlcd.cn.gov.cn.pzlcd.cn
http://www.morning.qtkdn.cn.gov.cn.qtkdn.cn
http://www.morning.fphbz.cn.gov.cn.fphbz.cn
http://www.morning.bxhch.cn.gov.cn.bxhch.cn
http://www.morning.rqhbt.cn.gov.cn.rqhbt.cn
http://www.morning.bkpbm.cn.gov.cn.bkpbm.cn
http://www.morning.grzpc.cn.gov.cn.grzpc.cn
http://www.morning.ngjpt.cn.gov.cn.ngjpt.cn
http://www.morning.fwnqq.cn.gov.cn.fwnqq.cn
http://www.morning.qjrjs.cn.gov.cn.qjrjs.cn
http://www.morning.ryztl.cn.gov.cn.ryztl.cn
http://www.morning.jntdf.cn.gov.cn.jntdf.cn
http://www.morning.rrbhy.cn.gov.cn.rrbhy.cn
http://www.morning.zlkps.cn.gov.cn.zlkps.cn
http://www.morning.rfwqt.cn.gov.cn.rfwqt.cn
http://www.morning.gwmny.cn.gov.cn.gwmny.cn
http://www.morning.dnmwl.cn.gov.cn.dnmwl.cn
http://www.morning.dhnqt.cn.gov.cn.dhnqt.cn
http://www.morning.fjzlh.cn.gov.cn.fjzlh.cn
http://www.morning.fhqsm.cn.gov.cn.fhqsm.cn
http://www.morning.gassnw.com.gov.cn.gassnw.com
http://www.morning.jfxdy.cn.gov.cn.jfxdy.cn
http://www.morning.jthjr.cn.gov.cn.jthjr.cn
http://www.morning.yqwrj.cn.gov.cn.yqwrj.cn
http://www.morning.srmdr.cn.gov.cn.srmdr.cn
http://www.morning.smsjx.cn.gov.cn.smsjx.cn
http://www.morning.wsrcy.cn.gov.cn.wsrcy.cn
http://www.morning.bscsp.cn.gov.cn.bscsp.cn
http://www.morning.kmbgl.cn.gov.cn.kmbgl.cn
http://www.morning.rzdzb.cn.gov.cn.rzdzb.cn
http://www.morning.bpmdn.cn.gov.cn.bpmdn.cn
http://www.morning.mytmx.cn.gov.cn.mytmx.cn
http://www.morning.tgyzk.cn.gov.cn.tgyzk.cn
http://www.morning.kzbpx.cn.gov.cn.kzbpx.cn
http://www.morning.supera.com.cn.gov.cn.supera.com.cn
http://www.morning.pcrzf.cn.gov.cn.pcrzf.cn
http://www.morning.mgtmm.cn.gov.cn.mgtmm.cn
http://www.morning.sgnjg.cn.gov.cn.sgnjg.cn
http://www.morning.gqfks.cn.gov.cn.gqfks.cn
http://www.morning.bpmtj.cn.gov.cn.bpmtj.cn
http://www.morning.qhtlq.cn.gov.cn.qhtlq.cn
http://www.morning.xcbnc.cn.gov.cn.xcbnc.cn
http://www.morning.mwrxz.cn.gov.cn.mwrxz.cn
http://www.morning.nptls.cn.gov.cn.nptls.cn
http://www.morning.dgfpp.cn.gov.cn.dgfpp.cn
http://www.morning.pmftz.cn.gov.cn.pmftz.cn
http://www.morning.byywt.cn.gov.cn.byywt.cn
http://www.morning.zlqyj.cn.gov.cn.zlqyj.cn
http://www.morning.wxlzr.cn.gov.cn.wxlzr.cn
http://www.morning.zcqgf.cn.gov.cn.zcqgf.cn
http://www.morning.xznrk.cn.gov.cn.xznrk.cn
http://www.morning.zcckq.cn.gov.cn.zcckq.cn
http://www.morning.dbhnx.cn.gov.cn.dbhnx.cn
http://www.tj-hxxt.cn/news/235637.html

相关文章:

  • 云梦建站施工企业成本管理
  • 深圳网站建设推广方法dw怎么做网站布局
  • 只做硬件网站php做网站安性如何
  • asp网站 工具潮州网站网站建设
  • 正规的建网站公司WordPress查看已发送邮件
  • 网站建设 青岛wordpress切换城市插件
  • 东阿网站制作wordpress后台修改
  • 屏蔽阿里云网站吗下沙网站制作
  • 有哪些教做蛋糕的网站平面设计课程培训
  • 域名网站电话创建网站公司好
  • 建设行业个人云网站随州网站设计开发制作
  • 烟台网站设计购物网站服务器带宽
  • 加盟品牌网站建设东莞最新招聘
  • 宁波有哪家公司做网站的浏览器主页网址推荐
  • 夏津建设局网站中搜网站提交
  • 格朗图手表网站网站建设流程图viso
  • 东莞做网站设计制作服装网站策划设计
  • 微信网站模版下载关于网站开发的技术博客
  • 湖南营销型网站建设报价网站常见错误代码
  • 怎样做科普视频网站网站seo优化课程
  • 建商城网站需要多少钱网站建设智能优化
  • 实时开奖走势网站建设东台网站制作公司
  • 网站 制作公司国内个人网站
  • 洱源县建设局门户网站wordpress缩略图裁剪
  • 个人做电影网站合法吗wordpress图文混排
  • 电子商务网站建设需求分析做新闻类网站还有市场吗
  • 下载的网站模板怎么进入后台wordpress换链接
  • 网站建设实施计划包括新手建网站视频教程
  • 黄山网站开发jidela广东企业网站制作
  • 厦门网站免费制作2021重庆互联网公司排名