Pytorch1.7复现PointNet++点云分割(含Open3D可视化)(文末有一个本身做的

[复制链接]
查看1320 | 回复7 | 2023-8-23 11:39:49 | 显示全部楼层 |阅读模式
  毕设必要,复现一下PointNet++的对象分类、零件分割和场景分割,找点灵感和思绪,做个踩坑记录。
  下载代码

https://github.com/yanx27/Pointnet_Pointnet2_pytorch
  我的运行情况是pytorch1.7+cuda11.0。
训练

  PointNet++代码能实现3D对象分类、对象零件分割和语义场景分割。
对象分类

  下载数据集ModelNet40,并存储在文件夹data/modelnet40_normal_resampled/。
  1. ## e.g., pointnet2_ssg without normal features
  2. python train_classification.py --model pointnet2_cls_ssg --log_dir pointnet2_cls_ssg
  3. python test_classification.py --log_dir pointnet2_cls_ssg
  4. ## e.g., pointnet2_ssg with normal features
  5. python train_classification.py --model pointnet2_cls_ssg --use_normals --log_dir pointnet2_cls_ssg_normal
  6. python test_classification.py --use_normals --log_dir pointnet2_cls_ssg_normal
  7. ## e.g., pointnet2_ssg with uniform sampling
  8. python train_classification.py --model pointnet2_cls_ssg --use_uniform_sample --log_dir pointnet2_cls_ssg_fps
  9. python test_classification.py --use_uniform_sample --log_dir pointnet2_cls_ssg_fps
复制代码


  • 主文件夹下运行代码python train_classification.py --model pointnet2_cls_ssg --log_dir pointnet2_cls_ssg时大概会报错:
    ImportError: cannot import name 'PointNetSetAbstraction'
    缘故原由是pointnet2_cls_ssg.py文件import时的工作目录时models文件夹,但是实际运行的工作目录时models的上级目录,因此必要在pointnet2_cls_ssg.py里把from pointnet2_utils import PointNetSetAbstraction改成from models.pointnet2_utils import PointNetSetAbstraction。
  参考README.md文件,分类不是我的主攻点,这里就略过了。
零件分割

  零件分割是将一个物体的各个零件分割出来,好比把椅子的椅子腿分出来。
  下载数据集ShapeNet,并存储在文件夹data/shapenetcore_partanno_segmentation_benchmark_v0_normal/。
  运行也很简单:
  1. ## e.g., pointnet2_msg
  2. python train_partseg.py --model pointnet2_part_seg_msg --normal --log_dir pointnet2_part_seg_msg
  3. python test_partseg.py --normal --log_dir pointnet2_part_seg_msg
复制代码
  shapenet数据集txt文件格式:前三个点是xyz,点云的位置坐标,后三个点是点云的法向信息,末了一个点是这个点所属的小种别,即1表示所属50个小种别中的第一个。
  写个代码用open3d可视化shapenet数据集的txt文件(随机配色):
  1. import open3d as o3d
  2. import numpy as np
  3. '''
  4. BASE_DIR = os.path.dirname(os.path.abspath(__file__))
  5. ROOT_DIR = os.path.dirname(BASE_DIR)
  6. sys.path.append(BASE_DIR)
  7. sys.path.append(os.path.join(ROOT_DIR, 'data_utils'))
  8. '''
  9. txt_path = '/home/lin/CV_AI_learning/Pointnet_Pointnet2_pytorch-master/data/shapenetcore_partanno_segmentation_benchmark_v0_normal/02691156/1b3c6b2fbcf834cf62b600da24e0965.txt'
  10. # 通过numpy读取txt点云
  11. pcd = np.genfromtxt(txt_path, delimiter=" ")
  12. pcd_vector = o3d.geometry.PointCloud()
  13. # 加载点坐标
  14. # txt点云前三个数值一般对应x、y、z坐标,可以通过open3d.geometry.PointCloud().points加载
  15. # 如果有法线或颜色,那么可以分别通过open3d.geometry.PointCloud().normals或open3d.geometry.PointCloud().colors加载
  16. pcd_vector.points = o3d.utility.Vector3dVector(pcd[:, :3])
  17. pcd_vector.colors = o3d.utility.Vector3dVector(pcd[:, 3:6])
  18. o3d.visualization.draw_geometries([pcd_vector])
复制代码
  GPU内存不敷减小一下batch_size。
  我这里训练了一下,接着代码的best_model.pth继续训练150轮,RTX3080单显卡训练一轮得六七分钟,150轮花了半天多的时间。
  网上的代码根本test一下分割的一些参数就竣事了,没有做可视化,参考这篇blog做了一下效果的可视化:PointNet++分割推测效果可视化。这篇blog首先用网络将输入图像的推测效果存为txt文件,然后用Matplotlib做可视化,过程有点复杂了,用open3d做可视化比力简便一点,代码如下:
  1. import tqdm
  2. import matplotlib
  3. import torch
  4. import os
  5. import warnings
  6. import numpy as np
  7. import open3d as o3d
  8. from torch.utils.data import Dataset
  9. import pybullet as p
  10. from models.pointnet2_part_seg_msg import get_model as pointnet2
  11. import time
  12. warnings.filterwarnings('ignore')
  13. matplotlib.use("Agg")
  14. def pc_normalize(pc):
  15.     centroid = np.mean(pc, axis=0)
  16.     pc = pc - centroid
  17.     m = np.max(np.sqrt(np.sum(pc ** 2, axis=1)))
  18.     pc = pc / m
  19.     return pc,centroid,m
  20. def generate_pointcloud(color_image, depth_image,width=1280,height=720,fov=50,near=0.01,far=5):
  21.     rgbd_image = o3d.geometry.RGBDImage.create_from_color_and_depth(color_image, depth_image,convert_rgb_to_intensity=False)
  22.     intrinsic = o3d.camera.PinholeCameraIntrinsic(o3d.camera.PinholeCameraIntrinsicParameters.Kinect2DepthCameraDefault )
  23.     aspect = width / height
  24.     projection_matrix = p.computeProjectionMatrixFOV(fov, aspect, near, far)
  25.     intrinsic.set_intrinsics(width=width, height=height, fx=projection_matrix[0]*width/2, fy=projection_matrix[5]*height/2, cx=width/2, cy=height/2)
  26.     point_cloud = o3d.geometry.PointCloud.create_from_rgbd_image(rgbd_image, intrinsic)
  27.    
  28.     point_cloud.estimate_normals( search_param=o3d.geometry.KDTreeSearchParamHybrid(radius=0.01, max_nn=30))
  29.     return point_cloud
  30. class PartNormalDataset(Dataset):
  31.     def __init__(self, point_cloud, npoints=2500, normal_channel=False):
  32.         self.npoints = npoints # 采样点数
  33.         self.cat = {}
  34.         self.normal_channel = normal_channel # 是否使用法向信息
  35.         position_data = np.asarray(point_cloud.points)
  36.         normal_data = np.asarray(point_cloud.normals)
  37.         self.raw_pcd = np.hstack([position_data,normal_data]).astype(np.float32)
  38.         self.cat = {'board':'12345678'}
  39.         # 输出的是元组,('Airplane',123.txt)
  40.         self.classes = {'board': 0}
  41.         data = self.raw_pcd
  42.         if not self.normal_channel:  # 判断是否使用法向信息
  43.             self.point_set = data[:, 0:3]
  44.         else:
  45.             self.point_set = data[:, 0:6]
  46.         self.point_set[:, 0:3],self.centroid,self.m = pc_normalize(self.point_set[:, 0:3]) # 做一个归一化
  47.         choice = np.random.choice(self.point_set.shape[0], self.npoints, replace=True) # 对一个类别中的数据进行随机采样 返回索引,允许重复采样
  48.         # resample
  49.         self.point_set =  self.point_set[choice, :] # 根据索引采样
  50.     def __getitem__(self, index):
  51.         cat = list(self.cat.keys())[0]
  52.         cls = self.classes[cat] # 将类名转换为索引
  53.         cls = np.array([cls]).astype(np.int32)
  54.         return self.point_set, cls, self.centroid, self.m # pointset是点云数据,cls十六个大类别,seg是一个数据中,不同点对应的小类别
  55.     def __len__(self):
  56.         return 1
  57. class Generate_txt_and_3d_img:
  58.     def __init__(self,num_classes,testDataLoader,model,visualize = False):
  59.         self.testDataLoader = testDataLoader
  60.         self.num_classes = num_classes
  61.         self.heat_map = False # 控制是否输出heatmap
  62.         self.visualize = visualize # 是否open3d可视化
  63.         self.model = model
  64.         self.generate_predict()
  65.         self.o3d_draw_3d_img()
  66.     def __getitem__(self, index):
  67.         return self.predict_pcd_colored
  68.     def generate_predict(self):
  69.         for _, (points, label,centroid,m) in tqdm.tqdm(enumerate(self.testDataLoader),
  70.                                                                       total=len(self.testDataLoader),smoothing=0.9):
  71.             #点云数据、整个图像的标签、每个点的标签、  没有归一化的点云数据(带标签)torch.Size([1, 7, 2048])
  72.             points = points.transpose(2, 1)
  73.             #print('1',target.shape) # 1 torch.Size([1, 2048])
  74.             xyz_feature_point = points[:, :6, :]
  75.             model = self.model
  76.             seg_pred, _ = model(points, self.to_categorical(label, 1))
  77.             seg_pred = seg_pred.cpu().data.numpy()
  78.             if self.heat_map:
  79.                 out =  np.asarray(np.sum(seg_pred,axis=2))
  80.                 seg_pred = ((out - np.min(out) / (np.max(out) - np.min(out))))
  81.             else:
  82.                 seg_pred = np.argmax(seg_pred, axis=-1)  # 获得网络的预测结果 b n c
  83.             seg_pred = np.concatenate([np.asarray(xyz_feature_point), seg_pred[:, None, :]],
  84.                     axis=1).transpose((0, 2, 1)).squeeze(0)
  85.             self.predict_pcd = seg_pred
  86.             self.centroid = centroid
  87.             self.m = m
  88.     def o3d_draw_3d_img(self):
  89.         pcd = self.predict_pcd
  90.         pcd_vector = o3d.geometry.PointCloud()
  91.         # 加载点坐标
  92.         pcd_vector.points = o3d.utility.Vector3dVector(self.m * pcd[:, :3] + self.centroid)
  93.         # colors = np.random.randint(255, size=(2,3))/255
  94.         colors = np.array([[0.8, 0.8, 0.8],[1,0,0]])
  95.         pcd_vector.colors = o3d.utility.Vector3dVector(colors[list(map(int,pcd[:, 6])),:])
  96.         if self.visualize:
  97.             coord_mesh = o3d.geometry.TriangleMesh.create_coordinate_frame(size = 0.1, origin = [0,0,0])
  98.             o3d.visualization.draw_geometries([pcd_vector,coord_mesh])
  99.         self.predict_pcd_colored = pcd_vector
  100.     def to_categorical(self,y, num_classes):
  101.         """ 1-hot encodes a tensor """
  102.         new_y = torch.eye(num_classes)[y.cpu().data.numpy(),]
  103.         if (y.is_cuda):
  104.             return new_y.cuda()
  105.         return new_y
  106. def load_models(model_dict={'PonintNet': [pointnet2(num_classes=2,normal_channel=True).eval(),r'./log/part_seg/pointnet2_part_seg_msg/checkpoints']}):
  107.     model = list(model_dict.values())[0][0]
  108.     checkpoints_dir = list(model_dict.values())[0][1]
  109.     weight_dict = torch.load(os.path.join(checkpoints_dir,'best_model.pth'))
  110.     model.load_state_dict(weight_dict['model_state_dict'])
  111.     return model
  112. class Open3dVisualizer():
  113.         def __init__(self):
  114.                 self.point_cloud = o3d.geometry.PointCloud()
  115.                 self.o3d_started = False
  116.                 self.vis = o3d.visualization.VisualizerWithKeyCallback()
  117.                 self.vis.create_window()
  118.         def __call__(self, points, colors):
  119.                 self.update(points, colors)
  120.                 return False
  121.         def update(self, points, colors):
  122.                 coord_mesh = o3d.geometry.TriangleMesh.create_coordinate_frame(size = 0.15, origin = [0,0,0])
  123.                 self.point_cloud.points = points
  124.                 self.point_cloud.colors = colors
  125.                 # self.point_cloud.transform([[1,0,0,0],[0,-1,0,0],[0,0,-1,0],[0,0,0,1]])
  126.                 # self.vis.clear_geometries()
  127.                 # Add geometries if it is the first time
  128.                 if not self.o3d_started:
  129.                         self.vis.add_geometry(self.point_cloud)
  130.                         self.vis.add_geometry(coord_mesh)
  131.                         self.o3d_started = True
  132.                 else:
  133.                         self.vis.update_geometry(self.point_cloud)
  134.                         self.vis.update_geometry(coord_mesh)
  135.                 self.vis.poll_events()
  136.                 self.vis.update_renderer()
  137. if __name__ =='__main__':
  138.    
  139.     num_classes = 2 # 填写数据集的类别数 如果是s3dis这里就填13   shapenet这里就填50
  140.    
  141.     color_image = o3d.io.read_image('image/rgb1.jpg')
  142.     depth_image = o3d.io.read_image('image/depth1.png')
  143.    
  144.     point_cloud = generate_pointcloud(color_image=color_image, depth_image=depth_image)
  145.     TEST_DATASET = PartNormalDataset(point_cloud,npoints=30000, normal_channel=True)
  146.     testDataLoader = torch.utils.data.DataLoader(TEST_DATASET, batch_size=1, shuffle=False, num_workers=0,drop_last=True)
  147.     predict_pcd = Generate_txt_and_3d_img(num_classes,testDataLoader,load_models(),visualize = True)
复制代码
  把之前的代码改成了针对单个点云推测的可视化,点云由GRB图像和深度图像天生,如果想直接输入点云本身稍微改下代码就可以了,目前仅针对shapenet数据集格式的数据。这里要留意如果训练的时间选择了--normal,那么normal_channel要改成True。
  看下训练效果,用modelnet40里的一个chair文件举行推测。
               可以看到这个椅子大抵是分成了四块,但是椅子靠背、腿分割地挺好的,就是扶手有一部门分割到了坐垫那里了,究竟训练时间不长。modelnet40数据集只是用来分类,并没有分割的标注,以是这里可视化了一下shapenet里标注好的椅子点云,看看椅子各个部位的分割(并非上面的椅子)。
           这里就比力显而易见地看出椅子分为靠背、扶手、坐垫、腿四个部门。
  开端观察到效果以后可以开始尝试本身制作数据集举行训练了,可以参考我写的这篇文章:《CloudCompare制作ShapeNet格式点云数据集》。
场景分割

  零件分割网络可以很容易地扩展到语义场景分割,点标志成为语义对象类而不是目标零件标志。
  在 Stanford 3D语义分析数据集上举行实行。该数据集包罗来自Matterport扫描仪的6个区域的3D扫描,包罗271个房间。扫描中的每个点都用13个种别(椅子、桌子、地板、墙壁等加上杂物)中的一个语义标签举行表明。
  先把文件下载过来: S3DIS ,存到文件夹data/s3dis/Stanford3dDataset_v1.2_Aligned_Version/.
  处理惩罚数据,数据会存到data/stanford_indoor3d/。
  1. cd data_utils
  2. python collect_indoor3d_data.py
复制代码
  运行:
  1. ## Check model in ./models
  2. ## e.g., pointnet2_ssg
  3. python train_semseg.py --model pointnet2_sem_seg --test_area 5 --log_dir pointnet2_sem_seg
  4. python test_semseg.py --log_dir pointnet2_sem_seg --test_area 5 --visual
复制代码
  上面的利用走完以后会在log/sem_seg/pointnet2_sem_seg/visual/天生推测效果的obj文件,可以用open3d举行可视化,就是不能用o3d.io.read_triangle_mesh函数来可视化obj文件,因为这里天生的obj文件还带了颜色信息用来表示语义信息,以是得读取成列表数据然后界说成o3d.geometry.PointCloud()变量表现,代码如下:
  1. import copy
  2. import numpy as np
  3. import open3d as o3d
  4. import os
  5. objFilePath = 'log/sem_seg/pointnet2_sem_seg/visual/Area_5_office_8_gt.obj'
  6. with open(objFilePath) as file:
  7.     points = []
  8.     while 1:
  9.         line = file.readline()
  10.         if not line:
  11.             break
  12.         strs = line.split(" ")
  13.         if strs[0] == "v":
  14.             points.append(np.array(strs[1:7],dtype=float))
  15.         if strs[0] == "vt":
  16.             break
  17. # points原本为列表,需要转变为矩阵,方便处理         
  18. pcd = np.array(points)
  19. pcd_vector = o3d.geometry.PointCloud()
  20. pcd_vector.points = o3d.utility.Vector3dVector(pcd[:, :3])
  21. pcd_vector.colors = o3d.utility.Vector3dVector(pcd[:,3:6])
  22. o3d.visualization.draw_geometries([pcd_vector])
复制代码
  康康Area_5里office_8的效果:
  原图:
               ground truth:

  predict:
         
     OK,大抵算是把这个PointNet++复现完了,侧重做了下点云分割,给毕设做准备。总的来讲,训练和推测的过程并不难,为了康康效果,可视化的部门倒是花了挺长时间。零件分割和场景分割本质上讲着实是一回事,就是在代码内里这两个分割用了差别的模型来训练。之后筹划本身制作数据集来训练一下,先拿零件分割的模型来做,究竟场景分割做成S3DIS情势的数据集有点贫苦。总之跟着这篇blog走肯定是能跑通PointNet++的。
  
     添加一个本身做的用pointnet++做的书缝辨认项目,GitHub内里有数据集和代码:https://github.com/struggler176393/Pointnet_book_seam。

来源:https://blog.csdn.net/astruggler/article/details/128354761
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

FrankJScott | 2025-5-7 00:49:02 | 显示全部楼层

Awesome Rtp Tinggi Info

In response to the man talking about situs slot yang terpercaya, aplikasi judi online slot, yang punya pragmatic play, situs game terbaru, slot wap, situs togel slot, situs togel lengkap, situs game slot resmi, slot pragmatic adalah, slot judi adalah,  I highly suggest this read this for live casino details or cara main slot game, spadegaming casino, bo togel dan slot, main slot adalah, web slot terbaru, situs yang terpercaya, joker play slot, togel dan slot, game deposit pulsa, slot yang, which is worth considering with this official statement about kasino online url together with bandar togel terbesar indonesia, agen resmi togel terbesar, judi online live, game judi slot online uang asli, situs slot togel terpercaya, situs slot terbagus, slot termudah menang, situs togel aman terpercaya, agen togel terbaik, situs slot jago, bearing in mind this a fantastic read about kasino online indonesia site which is also great. Also, have a look at this conversational tone about bonus kasino terbesar url and don't forget joker slot deposit pulsa, situs terpercaya slot online, play togel, situs game slot online resmi, bersama slot, main slot gampang menang, da slot, permainan online judi, deposit pulsa, situs slot online indonesia, bearing in mind this right here about table games forum not to mention agen toto online, game judi online, game judi slot online uang asli, bo togel slot, situs agen terpercaya,  inquiry about which is worth considering with permainan slot terbaru, situs togel pasaran hongkong terpercaya, situs slot pulsa, situs terpercaya, aplikasi togel resmi online,  for good measure. Check more @ New Login Tajir4D Info 48d8c60
回复

使用道具 举报

FrankJScott | 2025-5-7 02:21:38 | 显示全部楼层

Cool Laser Treatment Spots Face Sarasota Info

To the person talking about facial rejuvenation therapy, medical spa, derma care, skin restoration, vampire facial spa, skin care after laser treatment, co2 facial, laser skin treatment, rejuvenate medical aesthetics, the best facial treatment,  I highly recommend this super fast reply for laser treatment in my area site or skin tightening and lifting, red light rejuvenation, dermal filler face lift, best microneedling treatment, best lip injections, filler rha, skin care and laser, aesthetics medical, skin rejuvenation process, medical spa procedures, not to mention this awesome Best laser treatment Sarasota advice not to mention best filler for lip injections, skin rejuvenation facial, face rejuvenation procedures, facial do, laser treatment for skin tightening, skin therapy, aesthetics fillers, rf microneedling for skin tightening, vampire breast, rf skin tightening, together with this excellent laser for face treatment tips which is also great. Also, have a look at this recommended site on laser facial Sarasota blog alongside all lip filler with fat, fat dissolving, skin therapy, rf body, best threads for face lifting, med spa, the perfect derma, skin care spa treatments, florida medical aesthetics, lip injections florida, as well as this her comment is here on laser facial skin treatment site alongside all best facial for skin rejuvenation, aesthetics and wellness, skin florida, the perfect derma, aesthetics reviews,  read what he said on on top of lip filler lip flip, facial for rejuvenation, regenerative spa, injectables aesthetics, facial environ,  for good measure. Check more @ Top Poker Online Website 47ad43_
回复

使用道具 举报

FrankJScott | 2025-5-27 01:47:14 | 显示全部楼层

Top 7RAJATOGEL Tips

In reply to the lady talking about live draw sgp 6d hari ini tercepat, keluar nomor togel hongkong, situs togel angka jitu, prediksi no togel sgp hari ini, keluar angka sgp hari ini, angka togel singapura hari ini, situs togel online resmi terpercaya, keluaran togel singapore live, angka jitu togel hongkong malam ini, bocoran sgp langsung dari singapura hari ini,  I highly suggest this get more information about 7RAJATOGEL details or prediksi angka togel hk mlm ini, angka bocoran togel hari ini, angka togel singapura, hasil angka keluar sydney, data keluaran togel lengkap, data keluar sgp hari ini, judi togel online terpercaya, angka bocoran togel singapura hari ini, data keluar singapura hari ini, angka togel keluar hari ini, on top of this here on 7 RAJA TOGEL blog bearing in mind data keluaran sgp hk sdy, data keluar togel hari ini, prediksi togel sgp hari ini, situs togel terpercaya 2023, angka keluar sdy, keluaran angka hongkong hari ini, nomor togel hari ini singapore, angka jitu sdy hari ini pasti tembus, keluaran angka hongkong malam ini, angka nomor togel hari ini, which is worth considering with this the original source on 7 RAJA TOGEL info which is also great. Also, have a look at this killer deal about 7 RAJA TOGEL advice not forgetting sites such as keluaran angka hongkong malam ini, keluaran angka singapore, keluaran angka sgp hari ini, angka angka keluar, angka keluar sgp live draw, keluaran togel hari ini hk, angka keluar hongkong malam ini live result, rekomendasi situs togel terpercaya, data nomor togel hongkong, hasil angka keluar hk, not to mention this click for source  about 7 RAJA TOGEL advice and don't forget situs togel terbesar, link togel online terpercaya, data lengkap togel, togel keluaran singapore, situs togel angka jitu,  listen to this podcast on not forgetting sites such as data togel singapore 2022, prediksi nomor jitu togel singapore hari ini, angka togel singapore, togel sdy sgp hk 4d, cara rumus togel sgp,  for good measure. Check more @ Excellent Cross Body Phone Case Guide 3fd98ce
回复

使用道具 举报

FrankJScott | 2025-5-27 09:38:55 | 显示全部楼层

New DVLTOTO Info

For the person talking about judi casino online terbaik, slot online situs, link alternatif toto, slot online slot, www situs judi slot com, game slot terbaik, slot ini, situs judi slot online terbaru, bandar online terpercaya, situs togel terpercaya dan aman,  I highly suggest this best DVL TOTO blog or situs agen togel terpercaya, mesin slot login, game togel online, game slot online uang asli, link situs slot terpercaya, bandar togel online terpercaya, slot situs, judi bola, permainan judi togel, judi slot online terbaik, not forgetting sites such as this funny post on DVL TOTO url as well as game judi tembak ikan online, situs resmi judi online, toto online terbaik, situs togel slot 88, web judi slot terpercaya, situs judi resmi di indonesia, permainan seperti, situs judi slot online singapore, situs judi, situs online, alongside all this this contact form on DVLTOTO site which is also great. Also, have a look at this sources tell me about DVLTOTO link together with jenis jenis judi slot online, situs togel gampang menang, slot terbaru online, slot yang terpercaya, permainan online judi, permainan slot asli, slot yang mudah menang, judi slot terpercaya di indonesia, bandar togel terbesar indonesia, joker gaming slot online, alongside all this click this link about DVLTOTO blog not forgetting sites such as game perjudian, situs judi on, togel dan slot online, link game judi, slot online terbaik,  additional reading for and don't forget game slot tembak ikan, slot online terbesar, slot live casino, slot games slot, situs togel online resmi,  for good measure. Check more @ Top Rated TAJIR4D Login Info ce0e61d
回复

使用道具 举报

FrankJScott | 2025-5-27 11:01:04 | 显示全部楼层

Top 7 RAJA TOGEL Guide

For the guy asking about slot sbo, aplikasi togel dan slot, web slot resmi, situs judi online indonesia, situs togel aman dan terpercaya, situs game pragmatic, judi casino online terpercaya, slot situs online,  I suggest this https://www.tajir4d.com/ for situs pragmatic slot, nolimit city, deposit judi adalah, situs game slot online terpercaya, joker slot, slot resmi, slot online joker, situs togel yang aman dan terpercaya, also.
In reply to the lady talking about permainan yang mudah, situs judi slot online pg soft, slot mudah, mesin slot pragmatic play, slot judi adalah, keuntungan bermain slot online, togel online terbaik, bandar judi di indonesia,  I suggest this DVL TOTO for casino slot login, slot microgaming mudah menang, 10 situs judi slot online terpercaya, game slot tembak ikan, permainan pragmatic slot, permainan slot, judi permainan, game tembak ikan judi, also.
In response to the lady talking about situs togel online terpercaya, hasil angka keluar sidney, info angka togel hari ini, togel sdy, keluaran togel sidney, togel angka keluar sgp, pengeluaran togel hongkong hari ini, keluaran togel sgp,  I can vouch for this 7RAJATOGEL for angka togel hk hari ini, data togel sdy sgp hk, angka jitu togel sydney, togel sdy sgp dan hk, hasil pengeluaran hk, kumpulan situs slot terbaru, bocoran togel sgp hari ini, cara mendapatkan angka togel jitu, also. See More Top Rated 7RAJATOGE b48d8c6
回复

使用道具 举报

FrankJScott | 2025-5-28 01:15:35 | 显示全部楼层

Top Rated House Cleaning Service Info

For the lady talking about area rugs market, the best rugs for living room, looking for area rugs, rug and home, carpet mfg, hallway with carpet, drop rugs, best carpet design, custom living room rugs, interior design rug on carpet,  I highly suggest this learn more for house cleaning service link or custom rugs, types of carpets and rugs, custom carpet rug, pattern design carpet, best type of rug for living room, cheap living room rugs near me, best carpet, custom handmade rugs, era rugs, rug place holder, bearing in mind this updated house cleaning service link bearing in mind yarn carpets, carpet hand tufted, best type of carpet for home, carpet stores, carpet home design, carpet styles for living room, best area rug stores near me, the rug company handmade, hall room carpet, carpet over rug, as well as this visit website for house cleaning service link which is also great. Also, have a look at this on front page about house cleaning service site alongside all space carpet, area rugs near me now, work rugs, carpet shop rugs, best place to shop for rugs, stores with area rugs near me, living spaces carpet, shop area rugs near me, carpet and floor, custom rugs tufted, alongside all this her explanation on house cleaning service url and don't forget rug on a carpet floor, high quality living room rugs, living room carpet pinterest, carpet design for wall, shop rug,  moved here on together with best area carpets, beautiful area rugs for living room, cheap living room rugs near me, room with carpet, carpet and rug shop,  for good measure. Check more @ Awesome Melasma Treatment Sarasota Website 40_ef66
回复

使用道具 举报

Recommended Types Of Freshwater Shrimp Guide

To the lady talking about freshwater snails for betta tank, fresh water snail for sale, tropical fish aquarium store, order fresh water fish online, tropical fish for beginners uk, red cherry shrimp near me, live aquarium shrimp for sale near me, buy fresh water fish, aquarium fish, freshwater aquarium fish images, shrimp online uk, buy live tropical fish online uk, popular aquarium fishes, aquarium fish for sell, aquarium shrimp online, freshwater fish delivery uk, freshwater fish online shopping, cheap fish for sale online, nerite snail near me, fish for water tank,  I suggest this my review here for shrimp safe plants site for freshwater shrimp plants, tropical aquarium for beginners, cold water snails for aquarium, best tropical fish to buy, mixed fish aquarium, live freshwater fish free shipping, best tropical fish to get, best tank for snails, fish aquarium uk, snails and shrimp in same tank, aquarium yellow snail, blue shrimp fish tank, tropical freshwater snails, fish tank for sale uk, water aquarium fish, best fish for my aquarium, fish breeders uk, tropical fish store near me, freshwater aquarium fish for sale near me, tropical aquarium shrimp uk, the tropical fish, aquatic snail tank, snails in fish tank where did they come from, also. See More High Rated 7RAJATOGEL Guide 98ce0e6
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则