sksameermujahid commited on
Commit
968ab32
·
verified ·
1 Parent(s): 87a86b6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +999 -1
app.py CHANGED
@@ -614,10 +614,990 @@ def get_room_type_description(room_type):
614
  }
615
  return descriptions.get(room_type, f"A {room_type} area")
616
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
617
  @app.route('/')
618
  def index():
619
  """Main page for the image analyzer"""
620
- return render_template('index.html')
621
 
622
  @app.route('/analyze', methods=['POST'])
623
  def analyze_image():
@@ -785,6 +1765,24 @@ def health_check():
785
  }
786
  })
787
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
788
  @app.route('/static/<path:filename>')
789
  def static_files(filename):
790
  """Serve static files"""
 
614
  }
615
  return descriptions.get(room_type, f"A {room_type} area")
616
 
617
+ def assess_property_image_quality(room_classification, quality_analysis, object_detection, image_caption):
618
+ """Advanced AI-powered property image assessment using dynamic analysis"""
619
+ try:
620
+ # Initialize assessment components
621
+ assessment = {
622
+ "overall_score": 0,
623
+ "strengths": [],
624
+ "weaknesses": [],
625
+ "recommendations": [],
626
+ "market_appeal": {},
627
+ "technical_analysis": {},
628
+ "composition_analysis": {},
629
+ "professional_grade": False
630
+ }
631
+
632
+ # 1. Dynamic Room Classification Analysis (0-25 points)
633
+ room_score = 0
634
+ room_confidence = room_classification.get('confidence', 0)
635
+ room_type = room_classification.get('room_type', 'unknown')
636
+
637
+ # AI-based room type validation
638
+ if room_confidence > 0.8:
639
+ room_score = 25
640
+ assessment["strengths"].append(f"Clear {room_type} identification with high confidence")
641
+ elif room_confidence > 0.6:
642
+ room_score = 20
643
+ assessment["strengths"].append(f"Good {room_type} identification")
644
+ elif room_confidence > 0.4:
645
+ room_score = 15
646
+ assessment["weaknesses"].append(f"Uncertain room type identification")
647
+ else:
648
+ room_score = 5
649
+ assessment["weaknesses"].append("Poor room type identification")
650
+
651
+ # Cross-validate with object detection
652
+ object_room_inference = object_detection.get('analysis', {}).get('room_type_inference', {})
653
+ if room_type in object_room_inference:
654
+ object_confidence = object_room_inference[room_type]
655
+ if object_confidence > 0.5:
656
+ room_score += 5 # Bonus for consistency
657
+ assessment["strengths"].append("Object detection confirms room type")
658
+ else:
659
+ room_score -= 5 # Penalty for inconsistency
660
+ assessment["weaknesses"].append("Object detection contradicts room type")
661
+
662
+ # 2. Advanced Quality Analysis (0-30 points)
663
+ quality_score = 0
664
+ quality_metrics = quality_analysis.get('metrics', {})
665
+ quality_level = quality_analysis.get('quality_level', 'Unknown')
666
+ quality_issues = quality_analysis.get('issues', [])
667
+
668
+ # Dynamic quality scoring based on multiple factors
669
+ base_quality = quality_analysis.get('quality_score', 0)
670
+
671
+ # Technical quality factors
672
+ brightness_score = 0
673
+ brightness_mean = quality_metrics.get('brightness_mean', 128)
674
+ if 60 <= brightness_mean <= 180:
675
+ brightness_score = 8
676
+ elif 40 <= brightness_mean <= 200:
677
+ brightness_score = 5
678
+ else:
679
+ brightness_score = 2
680
+
681
+ contrast_score = 0
682
+ contrast = quality_metrics.get('contrast', 0)
683
+ if contrast > 40:
684
+ contrast_score = 8
685
+ elif contrast > 25:
686
+ contrast_score = 5
687
+ else:
688
+ contrast_score = 2
689
+
690
+ sharpness_score = 0
691
+ sharpness = quality_metrics.get('sharpness', 0)
692
+ if sharpness > 80:
693
+ sharpness_score = 8
694
+ elif sharpness > 50:
695
+ sharpness_score = 5
696
+ else:
697
+ sharpness_score = 2
698
+
699
+ noise_score = 0
700
+ noise_level = quality_metrics.get('noise_level', 0)
701
+ if noise_level < 0.05:
702
+ noise_score = 6
703
+ elif noise_level < 0.1:
704
+ noise_score = 4
705
+ else:
706
+ noise_score = 1
707
+
708
+ quality_score = brightness_score + contrast_score + sharpness_score + noise_score
709
+
710
+ # Add quality issues to weaknesses
711
+ for issue in quality_issues:
712
+ assessment["weaknesses"].append(f"Quality: {issue}")
713
+
714
+ # 3. Advanced Object Detection Analysis (0-25 points)
715
+ object_score = 0
716
+ object_analysis = object_detection.get('analysis', {})
717
+ detected_objects = object_detection.get('objects', [])
718
+
719
+ # Object richness scoring
720
+ total_objects = object_analysis.get('total_objects', 0)
721
+ if total_objects >= 8:
722
+ object_score += 10
723
+ assessment["strengths"].append("Rich object content enhances property appeal")
724
+ elif total_objects >= 5:
725
+ object_score += 7
726
+ assessment["strengths"].append("Good object variety")
727
+ elif total_objects >= 3:
728
+ object_score += 4
729
+ else:
730
+ object_score += 1
731
+ assessment["weaknesses"].append("Limited object content")
732
+
733
+ # Object relevance scoring
734
+ furniture_count = object_analysis.get('furniture_count', 0)
735
+ appliance_count = object_analysis.get('appliance_count', 0)
736
+ fixture_count = object_analysis.get('fixture_count', 0)
737
+
738
+ if furniture_count > 0:
739
+ object_score += 5
740
+ if appliance_count > 0:
741
+ object_score += 5
742
+ if fixture_count > 0:
743
+ object_score += 5
744
+
745
+ # Composition balance
746
+ composition_balance = object_analysis.get('composition_balance', 0)
747
+ if composition_balance > 0.6:
748
+ object_score += 5
749
+ assessment["strengths"].append("Well-balanced object composition")
750
+ elif composition_balance < 0.3:
751
+ object_score -= 3
752
+ assessment["weaknesses"].append("Poor object distribution")
753
+
754
+ # 4. Dynamic Caption Quality Analysis (0-20 points)
755
+ caption_score = 0
756
+ caption = image_caption.get('caption', '')
757
+
758
+ if caption:
759
+ # Analyze caption length and content
760
+ caption_length = len(caption.split())
761
+
762
+ # Check for real estate keywords
763
+ real_estate_keywords = ['room', 'kitchen', 'bathroom', 'bedroom', 'living', 'dining',
764
+ 'modern', 'luxury', 'spacious', 'bright', 'clean', 'furnished']
765
+
766
+ keyword_count = sum(1 for keyword in real_estate_keywords if keyword.lower() in caption.lower())
767
+
768
+ if caption_length >= 10 and keyword_count >= 3:
769
+ caption_score = 20
770
+ assessment["strengths"].append("Comprehensive and relevant caption")
771
+ elif caption_length >= 8 and keyword_count >= 2:
772
+ caption_score = 15
773
+ assessment["strengths"].append("Good descriptive caption")
774
+ elif caption_length >= 5:
775
+ caption_score = 10
776
+ else:
777
+ caption_score = 5
778
+ assessment["weaknesses"].append("Limited caption description")
779
+ else:
780
+ assessment["weaknesses"].append("No caption generated")
781
+
782
+ # 5. Calculate Overall Score with Dynamic Weighting
783
+ overall_score = room_score + quality_score + object_score + caption_score
784
+
785
+ # Normalize to 100-point scale
786
+ overall_score = min(100, overall_score)
787
+
788
+ # 6. Advanced Market Appeal Analysis
789
+ market_appeal = {}
790
+
791
+ # Professional grade determination
792
+ if overall_score >= 85:
793
+ assessment["professional_grade"] = True
794
+ market_appeal["level"] = "Premium"
795
+ market_appeal["description"] = "Professional-grade image suitable for luxury listings"
796
+ elif overall_score >= 75:
797
+ assessment["professional_grade"] = True
798
+ market_appeal["level"] = "Professional"
799
+ market_appeal["description"] = "High-quality image for professional listings"
800
+ elif overall_score >= 60:
801
+ market_appeal["level"] = "Standard"
802
+ market_appeal["description"] = "Acceptable quality for standard listings"
803
+ else:
804
+ market_appeal["level"] = "Needs Improvement"
805
+ market_appeal["description"] = "Image requires enhancement before listing"
806
+
807
+ # Target audience analysis
808
+ if room_type in ['kitchen', 'bathroom'] and quality_score > 20:
809
+ market_appeal["target_audience"] = "Home buyers, Investors"
810
+ elif room_type in ['bedroom', 'living room'] and object_score > 15:
811
+ market_appeal["target_audience"] = "Families, Young professionals"
812
+ else:
813
+ market_appeal["target_audience"] = "General buyers"
814
+
815
+ # 7. Dynamic Recommendations Generation
816
+ recommendations = []
817
+
818
+ # Quality-based recommendations
819
+ if brightness_mean < 50:
820
+ recommendations.append("Increase lighting or use HDR techniques")
821
+ elif brightness_mean > 200:
822
+ recommendations.append("Reduce exposure to avoid overexposure")
823
+
824
+ if contrast < 25:
825
+ recommendations.append("Enhance contrast in post-processing")
826
+
827
+ if sharpness < 50:
828
+ recommendations.append("Use tripod or image stabilization for sharper photos")
829
+
830
+ if noise_level > 0.1:
831
+ recommendations.append("Use noise reduction software")
832
+
833
+ # Object-based recommendations
834
+ if total_objects < 3:
835
+ recommendations.append("Include more furniture or decorative elements")
836
+
837
+ if composition_balance < 0.4:
838
+ recommendations.append("Reposition camera for better object distribution")
839
+
840
+ # Room-specific recommendations
841
+ if room_type == 'kitchen' and appliance_count < 2:
842
+ recommendations.append("Highlight kitchen appliances and features")
843
+ elif room_type == 'bathroom' and fixture_count < 2:
844
+ recommendations.append("Showcase bathroom fixtures and amenities")
845
+
846
+ # Technical recommendations
847
+ if not assessment["professional_grade"]:
848
+ recommendations.append("Consider professional photography services")
849
+
850
+ assessment["recommendations"] = recommendations
851
+ assessment["overall_score"] = overall_score
852
+ assessment["market_appeal"] = market_appeal
853
+
854
+ # 8. Technical Analysis Summary
855
+ assessment["technical_analysis"] = {
856
+ "room_classification_score": room_score,
857
+ "quality_analysis_score": quality_score,
858
+ "object_detection_score": object_score,
859
+ "caption_quality_score": caption_score,
860
+ "composition_balance": composition_balance,
861
+ "object_density": object_analysis.get('object_density', 0),
862
+ "quality_metrics_summary": {
863
+ "brightness": round(brightness_mean, 1),
864
+ "contrast": round(contrast, 1),
865
+ "sharpness": round(sharpness, 1),
866
+ "noise_level": round(noise_level, 3)
867
+ }
868
+ }
869
+
870
+ return assessment
871
+
872
+ except Exception as e:
873
+ logger.error(f"Error in property assessment: {str(e)}")
874
+ return {
875
+ "overall_score": 0,
876
+ "strengths": [],
877
+ "weaknesses": ["Assessment failed due to technical error"],
878
+ "recommendations": ["Please try again with a different image"],
879
+ "market_appeal": {"level": "Unknown", "description": "Unable to assess"},
880
+ "professional_grade": False,
881
+ "technical_analysis": {}
882
+ }
883
+
884
+ def estimate_room_size(image, room_type='unknown'):
885
+ """Advanced AI-powered room size estimation using multiple analysis methods"""
886
+ try:
887
+ # Convert PIL image to numpy array
888
+ img_array = np.array(image)
889
+
890
+ # Get image dimensions
891
+ height, width = img_array.shape[:2]
892
+ image_area = height * width
893
+
894
+ # 1. Object-based size estimation
895
+ object_analysis = detect_objects_advanced(image)
896
+ detected_objects = object_analysis.get('objects', [])
897
+ object_analysis_data = object_analysis.get('analysis', {})
898
+
899
+ # Categorize objects by typical sizes
900
+ large_furniture = [obj for obj in detected_objects
901
+ if obj['label'].lower() in ['bed', 'sofa', 'couch', 'dining table', 'kitchen island']]
902
+ medium_furniture = [obj for obj in detected_objects
903
+ if obj['label'].lower() in ['chair', 'desk', 'cabinet', 'dresser', 'nightstand']]
904
+ small_furniture = [obj for obj in detected_objects
905
+ if obj['label'].lower() in ['lamp', 'plant', 'vase', 'picture frame']]
906
+
907
+ # 2. Object density analysis
908
+ total_objects = len(detected_objects)
909
+ object_density = object_analysis_data.get('object_density', 0)
910
+
911
+ # 3. Perspective and depth analysis
912
+ # Analyze object positioning for depth perception
913
+ if detected_objects:
914
+ # Calculate object distribution across image
915
+ x_positions = []
916
+ y_positions = []
917
+ object_sizes = []
918
+
919
+ for obj in detected_objects:
920
+ bbox = obj['bbox']
921
+ x_center = (bbox[0] + bbox[2]) / 2
922
+ y_center = (bbox[1] + bbox[3]) / 2
923
+ obj_width = bbox[2] - bbox[0]
924
+ obj_height = bbox[3] - bbox[1]
925
+ obj_area = obj_width * obj_height
926
+
927
+ x_positions.append(x_center)
928
+ y_positions.append(y_center)
929
+ object_sizes.append(obj_area)
930
+
931
+ # Calculate spatial distribution
932
+ x_variance = float(np.var(x_positions)) if len(x_positions) > 1 else 0.0
933
+ y_variance = float(np.var(y_positions)) if len(y_positions) > 1 else 0.0
934
+ avg_object_size = float(np.mean(object_sizes)) if object_sizes else 0.0
935
+
936
+ # Depth perception indicators
937
+ size_variance = float(np.var(object_sizes)) if len(object_sizes) > 1 else 0.0
938
+ depth_indicator = float(size_variance / (avg_object_size + 1e-8))
939
+ else:
940
+ x_variance = y_variance = avg_object_size = depth_indicator = 0.0
941
+
942
+ # 4. Advanced size estimation algorithm
943
+ size_score = 0
944
+ size_factors = {}
945
+
946
+ # Object count factor (0-30 points)
947
+ if total_objects >= 10:
948
+ size_score += 30
949
+ size_factors["object_count"] = "Very High"
950
+ elif total_objects >= 7:
951
+ size_score += 25
952
+ size_factors["object_count"] = "High"
953
+ elif total_objects >= 5:
954
+ size_score += 20
955
+ size_factors["object_count"] = "Medium-High"
956
+ elif total_objects >= 3:
957
+ size_score += 15
958
+ size_factors["object_count"] = "Medium"
959
+ elif total_objects >= 1:
960
+ size_score += 10
961
+ size_factors["object_count"] = "Low"
962
+ else:
963
+ size_factors["object_count"] = "Very Low"
964
+
965
+ # Furniture type factor (0-25 points)
966
+ furniture_score = 0
967
+ if len(large_furniture) >= 3:
968
+ furniture_score = 25
969
+ size_factors["furniture_type"] = "Multiple large pieces"
970
+ elif len(large_furniture) >= 2:
971
+ furniture_score = 20
972
+ size_factors["furniture_type"] = "Several large pieces"
973
+ elif len(large_furniture) >= 1:
974
+ furniture_score = 15
975
+ size_factors["furniture_type"] = "Some large pieces"
976
+ elif len(medium_furniture) >= 3:
977
+ furniture_score = 12
978
+ size_factors["furniture_type"] = "Multiple medium pieces"
979
+ elif len(medium_furniture) >= 1:
980
+ furniture_score = 8
981
+ size_factors["furniture_type"] = "Some medium pieces"
982
+ else:
983
+ furniture_score = 5
984
+ size_factors["furniture_type"] = "Small pieces only"
985
+
986
+ size_score += furniture_score
987
+
988
+ # Object density factor (0-20 points)
989
+ if object_density > 15:
990
+ size_score += 20
991
+ size_factors["object_density"] = "Very High"
992
+ elif object_density > 10:
993
+ size_score += 15
994
+ size_factors["object_density"] = "High"
995
+ elif object_density > 5:
996
+ size_score += 10
997
+ size_factors["object_density"] = "Medium"
998
+ elif object_density > 2:
999
+ size_score += 5
1000
+ size_factors["object_density"] = "Low"
1001
+ else:
1002
+ size_factors["object_density"] = "Very Low"
1003
+
1004
+ # Spatial distribution factor (0-15 points)
1005
+ spatial_score = 0
1006
+ if x_variance > 10000 and y_variance > 10000:
1007
+ spatial_score = 15
1008
+ size_factors["spatial_distribution"] = "Wide spread"
1009
+ elif x_variance > 5000 or y_variance > 5000:
1010
+ spatial_score = 10
1011
+ size_factors["spatial_distribution"] = "Moderate spread"
1012
+ elif x_variance > 1000 or y_variance > 1000:
1013
+ spatial_score = 5
1014
+ size_factors["spatial_distribution"] = "Limited spread"
1015
+ else:
1016
+ size_factors["spatial_distribution"] = "Concentrated"
1017
+
1018
+ size_score += spatial_score
1019
+
1020
+ # Depth perception factor (0-10 points)
1021
+ if depth_indicator > 0.5:
1022
+ size_score += 10
1023
+ size_factors["depth_perception"] = "Strong depth"
1024
+ elif depth_indicator > 0.2:
1025
+ size_score += 7
1026
+ size_factors["depth_perception"] = "Moderate depth"
1027
+ elif depth_indicator > 0.1:
1028
+ size_score += 4
1029
+ size_factors["depth_perception"] = "Limited depth"
1030
+ else:
1031
+ size_factors["depth_perception"] = "Flat perspective"
1032
+
1033
+ # 5. Dynamic size classification
1034
+ if size_score >= 80:
1035
+ estimated_size = "Very Large (300+ sq ft)"
1036
+ size_category = "XL"
1037
+ confidence = "High"
1038
+ elif size_score >= 65:
1039
+ estimated_size = "Large (200-300 sq ft)"
1040
+ size_category = "L"
1041
+ confidence = "High"
1042
+ elif size_score >= 50:
1043
+ estimated_size = "Medium-Large (150-200 sq ft)"
1044
+ size_category = "ML"
1045
+ confidence = "Medium"
1046
+ elif size_score >= 35:
1047
+ estimated_size = "Medium (100-150 sq ft)"
1048
+ size_category = "M"
1049
+ confidence = "Medium"
1050
+ elif size_score >= 20:
1051
+ estimated_size = "Small-Medium (80-100 sq ft)"
1052
+ size_category = "SM"
1053
+ confidence = "Medium"
1054
+ elif size_score >= 10:
1055
+ estimated_size = "Small (50-80 sq ft)"
1056
+ size_category = "S"
1057
+ confidence = "Low"
1058
+ else:
1059
+ estimated_size = "Very Small (<50 sq ft)"
1060
+ size_category = "XS"
1061
+ confidence = "Low"
1062
+
1063
+ # 6. Room type specific adjustments
1064
+ # Use the room_type parameter passed to the function
1065
+
1066
+ # Adjust size based on room type expectations
1067
+ if room_type == 'kitchen':
1068
+ if size_category in ['XS', 'S']:
1069
+ estimated_size = "Compact Kitchen (50-80 sq ft)"
1070
+ elif size_category in ['M', 'ML']:
1071
+ estimated_size = "Standard Kitchen (100-150 sq ft)"
1072
+ else:
1073
+ estimated_size = "Large Kitchen (150+ sq ft)"
1074
+ elif room_type == 'bathroom':
1075
+ if size_category in ['XS', 'S']:
1076
+ estimated_size = "Standard Bathroom (40-60 sq ft)"
1077
+ elif size_category in ['M', 'ML']:
1078
+ estimated_size = "Large Bathroom (60-100 sq ft)"
1079
+ else:
1080
+ estimated_size = "Luxury Bathroom (100+ sq ft)"
1081
+ elif room_type == 'bedroom':
1082
+ if size_category in ['XS', 'S']:
1083
+ estimated_size = "Small Bedroom (80-120 sq ft)"
1084
+ elif size_category in ['M', 'ML']:
1085
+ estimated_size = "Standard Bedroom (120-180 sq ft)"
1086
+ else:
1087
+ estimated_size = "Large Bedroom (180+ sq ft)"
1088
+
1089
+ # 7. Confidence calculation
1090
+ confidence_factors = []
1091
+ if total_objects >= 5:
1092
+ confidence_factors.append("Multiple objects detected")
1093
+ if len(large_furniture) >= 1:
1094
+ confidence_factors.append("Large furniture present")
1095
+ if object_density > 5:
1096
+ confidence_factors.append("Good object density")
1097
+ if x_variance > 5000 and y_variance > 5000:
1098
+ confidence_factors.append("Good spatial distribution")
1099
+
1100
+ if len(confidence_factors) >= 3:
1101
+ confidence = "High"
1102
+ elif len(confidence_factors) >= 2:
1103
+ confidence = "Medium"
1104
+ else:
1105
+ confidence = "Low"
1106
+
1107
+ return {
1108
+ "estimated_size": estimated_size,
1109
+ "size_category": size_category,
1110
+ "confidence": confidence,
1111
+ "confidence_factors": confidence_factors,
1112
+ "size_score": int(size_score), # Convert to Python int
1113
+ "size_factors": size_factors,
1114
+ "object_analysis": {
1115
+ "total_objects": int(total_objects), # Convert to Python int
1116
+ "large_furniture": int(len(large_furniture)), # Convert to Python int
1117
+ "medium_furniture": int(len(medium_furniture)), # Convert to Python int
1118
+ "small_furniture": int(len(small_furniture)), # Convert to Python int
1119
+ "object_density": float(round(object_density, 2)), # Convert to Python float
1120
+ "spatial_variance": {
1121
+ "x_variance": float(round(x_variance, 2)), # Convert to Python float
1122
+ "y_variance": float(round(y_variance, 2)) # Convert to Python float
1123
+ },
1124
+ "depth_indicator": float(round(depth_indicator, 3)) # Convert to Python float
1125
+ }
1126
+ }
1127
+
1128
+ except Exception as e:
1129
+ logger.error(f"Error in room size estimation: {str(e)}")
1130
+ return {
1131
+ "estimated_size": "Unable to estimate",
1132
+ "size_category": "Unknown",
1133
+ "confidence": "Low",
1134
+ "confidence_factors": ["Estimation failed"],
1135
+ "size_score": 0,
1136
+ "size_factors": {},
1137
+ "object_analysis": {
1138
+ "total_objects": 0,
1139
+ "large_furniture": 0,
1140
+ "medium_furniture": 0,
1141
+ "small_furniture": 0,
1142
+ "object_density": 0.0,
1143
+ "spatial_variance": {"x_variance": 0.0, "y_variance": 0.0},
1144
+ "depth_indicator": 0.0
1145
+ }
1146
+ }
1147
+
1148
+ def generate_property_insights(room_classification, quality_analysis, object_detection, image_caption):
1149
+ """Advanced AI-powered property insights generation using dynamic analysis"""
1150
+ try:
1151
+ insights = {
1152
+ "marketing_tips": [],
1153
+ "target_audience": [],
1154
+ "pricing_considerations": [],
1155
+ "improvement_suggestions": [],
1156
+ "market_positioning": {},
1157
+ "competitive_analysis": {},
1158
+ "investment_potential": {},
1159
+ "staging_recommendations": []
1160
+ }
1161
+
1162
+ # Extract key data
1163
+ room_type = room_classification.get('room_type', 'unknown')
1164
+ room_confidence = room_classification.get('confidence', 0)
1165
+ quality_score = quality_analysis.get('quality_score', 0)
1166
+ quality_level = quality_analysis.get('quality_level', 'Unknown')
1167
+ object_analysis = object_detection.get('analysis', {})
1168
+ detected_objects = object_detection.get('objects', [])
1169
+ caption = image_caption.get('caption', '')
1170
+
1171
+ # 1. Dynamic Marketing Tips Generation
1172
+ marketing_tips = []
1173
+
1174
+ # Quality-based marketing tips
1175
+ if quality_score >= 80:
1176
+ marketing_tips.append("Highlight the professional photography quality in listings")
1177
+ marketing_tips.append("Use this image as a primary showcase photo")
1178
+ elif quality_score >= 60:
1179
+ marketing_tips.append("Consider this image for secondary photo positions")
1180
+ else:
1181
+ marketing_tips.append("Use this image sparingly or improve before listing")
1182
+
1183
+ # Room-specific marketing tips
1184
+ if room_type == 'kitchen':
1185
+ marketing_tips.append("Emphasize modern kitchen features and appliances")
1186
+ marketing_tips.append("Highlight the kitchen as the heart of the home")
1187
+ if object_analysis.get('appliance_count', 0) >= 3:
1188
+ marketing_tips.append("Showcase the fully equipped kitchen")
1189
+ elif room_type == 'bathroom':
1190
+ marketing_tips.append("Focus on cleanliness and modern fixtures")
1191
+ marketing_tips.append("Highlight bathroom luxury and comfort")
1192
+ elif room_type == 'bedroom':
1193
+ marketing_tips.append("Emphasize comfort and relaxation potential")
1194
+ marketing_tips.append("Highlight bedroom size and natural light")
1195
+ elif room_type == 'living room':
1196
+ marketing_tips.append("Showcase entertainment and family gathering spaces")
1197
+ marketing_tips.append("Highlight living room versatility and flow")
1198
+
1199
+ # Object-based marketing tips
1200
+ furniture_count = object_analysis.get('furniture_count', 0)
1201
+ if furniture_count >= 5:
1202
+ marketing_tips.append("Emphasize the fully furnished and move-in ready aspect")
1203
+ elif furniture_count >= 3:
1204
+ marketing_tips.append("Highlight the well-appointed space")
1205
+
1206
+ # 2. Advanced Target Audience Analysis
1207
+ target_audience = []
1208
+
1209
+ # Room type based targeting
1210
+ if room_type == 'kitchen':
1211
+ target_audience.extend(["Home chefs", "Families", "Entertainment enthusiasts"])
1212
+ elif room_type == 'bathroom':
1213
+ target_audience.extend(["Luxury seekers", "Families", "Young professionals"])
1214
+ elif room_type == 'bedroom':
1215
+ target_audience.extend(["Families", "Young professionals", "Students"])
1216
+ elif room_type == 'living room':
1217
+ target_audience.extend(["Families", "Entertainment lovers", "Social people"])
1218
+
1219
+ # Quality-based targeting
1220
+ if quality_score >= 85:
1221
+ target_audience.append("Luxury buyers")
1222
+ elif quality_score >= 70:
1223
+ target_audience.append("Professional buyers")
1224
+ else:
1225
+ target_audience.append("Budget-conscious buyers")
1226
+
1227
+ # Object-based targeting
1228
+ if object_analysis.get('appliance_count', 0) >= 3:
1229
+ target_audience.append("Modern lifestyle seekers")
1230
+
1231
+ if object_analysis.get('fixture_count', 0) >= 3:
1232
+ target_audience.append("Quality-conscious buyers")
1233
+
1234
+ # 3. Dynamic Pricing Considerations
1235
+ pricing_considerations = []
1236
+
1237
+ # Quality impact on pricing
1238
+ if quality_score >= 80:
1239
+ pricing_considerations.append("High-quality images can support premium pricing")
1240
+ elif quality_score >= 60:
1241
+ pricing_considerations.append("Standard image quality supports market-rate pricing")
1242
+ else:
1243
+ pricing_considerations.append("Image quality may limit pricing potential")
1244
+
1245
+ # Room type pricing impact
1246
+ if room_type == 'kitchen':
1247
+ pricing_considerations.append("Kitchen quality significantly impacts property value")
1248
+ if object_analysis.get('appliance_count', 0) >= 3:
1249
+ pricing_considerations.append("Modern appliances justify higher pricing")
1250
+ elif room_type == 'bathroom':
1251
+ pricing_considerations.append("Bathroom luxury can command premium pricing")
1252
+ elif room_type == 'bedroom':
1253
+ pricing_considerations.append("Bedroom appeal affects family buyer pricing")
1254
+
1255
+ # Object density pricing impact
1256
+ object_density = object_analysis.get('object_density', 0)
1257
+ if object_density > 10:
1258
+ pricing_considerations.append("Rich content suggests well-appointed property")
1259
+ elif object_density < 3:
1260
+ pricing_considerations.append("Sparse content may suggest staging needed")
1261
+
1262
+ # 4. AI-Powered Improvement Suggestions
1263
+ improvement_suggestions = []
1264
+
1265
+ # Technical improvements
1266
+ if quality_score < 70:
1267
+ improvement_suggestions.append("Improve lighting and exposure for better image quality")
1268
+ improvement_suggestions.append("Use professional photography equipment")
1269
+
1270
+ # Composition improvements
1271
+ composition_balance = object_analysis.get('composition_balance', 0)
1272
+ if composition_balance < 0.4:
1273
+ improvement_suggestions.append("Reposition camera for better composition")
1274
+ improvement_suggestions.append("Follow rule of thirds for better framing")
1275
+
1276
+ # Content improvements
1277
+ total_objects = object_analysis.get('total_objects', 0)
1278
+ if total_objects < 3:
1279
+ improvement_suggestions.append("Add more furniture or decorative elements")
1280
+ improvement_suggestions.append("Consider professional staging")
1281
+
1282
+ # Room-specific improvements
1283
+ if room_type == 'kitchen' and object_analysis.get('appliance_count', 0) < 2:
1284
+ improvement_suggestions.append("Highlight kitchen appliances and features")
1285
+ elif room_type == 'bathroom' and object_analysis.get('fixture_count', 0) < 2:
1286
+ improvement_suggestions.append("Showcase bathroom fixtures and amenities")
1287
+
1288
+ # 5. Advanced Market Positioning Analysis
1289
+ market_positioning = {}
1290
+
1291
+ # Quality positioning
1292
+ if quality_score >= 85:
1293
+ market_positioning["quality_tier"] = "Premium"
1294
+ market_positioning["positioning_statement"] = "Luxury property with professional presentation"
1295
+ elif quality_score >= 70:
1296
+ market_positioning["quality_tier"] = "Professional"
1297
+ market_positioning["positioning_statement"] = "Well-presented property suitable for discerning buyers"
1298
+ elif quality_score >= 50:
1299
+ market_positioning["quality_tier"] = "Standard"
1300
+ market_positioning["positioning_statement"] = "Standard property presentation"
1301
+ else:
1302
+ market_positioning["quality_tier"] = "Needs Improvement"
1303
+ market_positioning["positioning_statement"] = "Property requires better presentation"
1304
+
1305
+ # Room type positioning
1306
+ if room_type in ['kitchen', 'bathroom']:
1307
+ market_positioning["focus_area"] = "High-value rooms"
1308
+ market_positioning["key_message"] = f"Showcase {room_type} quality and features"
1309
+ else:
1310
+ market_positioning["focus_area"] = "Living spaces"
1311
+ market_positioning["key_message"] = f"Highlight {room_type} comfort and functionality"
1312
+
1313
+ # 6. Competitive Analysis
1314
+ competitive_analysis = {}
1315
+
1316
+ # Quality comparison
1317
+ if quality_score >= 80:
1318
+ competitive_analysis["quality_advantage"] = "Above average"
1319
+ competitive_analysis["differentiation"] = "Professional presentation sets property apart"
1320
+ elif quality_score >= 60:
1321
+ competitive_analysis["quality_advantage"] = "Competitive"
1322
+ competitive_analysis["differentiation"] = "Standard presentation meets market expectations"
1323
+ else:
1324
+ competitive_analysis["quality_advantage"] = "Below average"
1325
+ competitive_analysis["differentiation"] = "Needs improvement to compete effectively"
1326
+
1327
+ # Content comparison
1328
+ if object_analysis.get('total_objects', 0) >= 8:
1329
+ competitive_analysis["content_advantage"] = "Rich content"
1330
+ competitive_analysis["content_message"] = "Well-appointed space with many features"
1331
+ elif object_analysis.get('total_objects', 0) >= 5:
1332
+ competitive_analysis["content_advantage"] = "Good content"
1333
+ competitive_analysis["content_message"] = "Adequate feature representation"
1334
+ else:
1335
+ competitive_analysis["content_advantage"] = "Limited content"
1336
+ competitive_analysis["content_message"] = "Consider adding more features"
1337
+
1338
+ # 7. Investment Potential Analysis
1339
+ investment_potential = {}
1340
+
1341
+ # Quality impact on investment
1342
+ if quality_score >= 80:
1343
+ investment_potential["presentation_value"] = "High"
1344
+ investment_potential["roi_potential"] = "Excellent - professional presentation supports premium pricing"
1345
+ elif quality_score >= 60:
1346
+ investment_potential["presentation_value"] = "Medium"
1347
+ investment_potential["roi_potential"] = "Good - standard presentation supports market pricing"
1348
+ else:
1349
+ investment_potential["presentation_value"] = "Low"
1350
+ investment_potential["roi_potential"] = "Limited - poor presentation may reduce pricing potential"
1351
+
1352
+ # Room type investment impact
1353
+ if room_type in ['kitchen', 'bathroom']:
1354
+ investment_potential["room_value"] = "High-impact rooms"
1355
+ investment_potential["investment_priority"] = "Focus on these rooms for maximum ROI"
1356
+ else:
1357
+ investment_potential["room_value"] = "Standard rooms"
1358
+ investment_potential["investment_priority"] = "Ensure adequate presentation quality"
1359
+
1360
+ # 8. Dynamic Staging Recommendations
1361
+ staging_recommendations = []
1362
+
1363
+ # Object-based staging
1364
+ if object_analysis.get('furniture_count', 0) < 2:
1365
+ staging_recommendations.append("Add key furniture pieces to define the space")
1366
+
1367
+ if object_analysis.get('appliance_count', 0) < 2 and room_type == 'kitchen':
1368
+ staging_recommendations.append("Highlight kitchen appliances and modern features")
1369
+
1370
+ if object_analysis.get('fixture_count', 0) < 2 and room_type == 'bathroom':
1371
+ staging_recommendations.append("Showcase bathroom fixtures and luxury amenities")
1372
+
1373
+ # Quality-based staging
1374
+ if quality_score < 60:
1375
+ staging_recommendations.append("Improve lighting and staging for better presentation")
1376
+
1377
+ # Room-specific staging
1378
+ if room_type == 'bedroom':
1379
+ staging_recommendations.append("Create a welcoming and comfortable bedroom atmosphere")
1380
+ elif room_type == 'living room':
1381
+ staging_recommendations.append("Stage for entertainment and family gatherings")
1382
+
1383
+ # Update insights dictionary
1384
+ insights.update({
1385
+ "marketing_tips": marketing_tips,
1386
+ "target_audience": list(set(target_audience)), # Remove duplicates
1387
+ "pricing_considerations": pricing_considerations,
1388
+ "improvement_suggestions": improvement_suggestions,
1389
+ "market_positioning": market_positioning,
1390
+ "competitive_analysis": competitive_analysis,
1391
+ "investment_potential": investment_potential,
1392
+ "staging_recommendations": staging_recommendations
1393
+ })
1394
+
1395
+ return insights
1396
+
1397
+ except Exception as e:
1398
+ logger.error(f"Error in generating property insights: {str(e)}")
1399
+ return {
1400
+ "marketing_tips": ["Unable to generate marketing tips"],
1401
+ "target_audience": ["General buyers"],
1402
+ "pricing_considerations": ["Standard market pricing"],
1403
+ "improvement_suggestions": ["Improve image quality and content"],
1404
+ "market_positioning": {"quality_tier": "Unknown"},
1405
+ "competitive_analysis": {"quality_advantage": "Unknown"},
1406
+ "investment_potential": {"presentation_value": "Unknown"},
1407
+ "staging_recommendations": ["Consider professional staging"]
1408
+ }
1409
+
1410
+ def analyze_scene_with_clip(image, room_type):
1411
+ """Advanced scene understanding using CLIP model"""
1412
+ try:
1413
+ if not clip_processor or not clip_model:
1414
+ return {'scene_concepts': [], 'style_analysis': {}}
1415
+
1416
+ # Define comprehensive real estate concepts
1417
+ real_estate_concepts = [
1418
+ # Style concepts
1419
+ "modern design", "traditional style", "contemporary", "luxury", "minimalist", "rustic", "industrial",
1420
+ "scandinavian", "mediterranean", "asian fusion", "art deco", "mid-century modern",
1421
+
1422
+ # Quality indicators
1423
+ "high-end finishes", "premium materials", "custom details", "architectural features",
1424
+ "natural light", "open floor plan", "high ceilings", "hardwood floors", "granite countertops",
1425
+
1426
+ # Functionality
1427
+ "functional layout", "efficient design", "storage solutions", "entertainment space",
1428
+ "home office", "flexible space", "outdoor living", "smart home features",
1429
+
1430
+ # Room-specific concepts
1431
+ "gourmet kitchen", "spa-like bathroom", "master suite", "entertainment room",
1432
+ "dining area", "living space", "bedroom retreat", "home gym", "wine cellar"
1433
+ ]
1434
+
1435
+ # Process image and text
1436
+ inputs = clip_processor(images=image, text=real_estate_concepts, return_tensors="pt", padding=True)
1437
+
1438
+ with torch.no_grad():
1439
+ outputs = clip_model(**inputs)
1440
+ logits_per_image = outputs.logits_per_image
1441
+ probs = logits_per_image.softmax(dim=-1)
1442
+
1443
+ # Get top matches
1444
+ top_concepts = []
1445
+ for i, prob in enumerate(probs[0]):
1446
+ if prob > 0.2: # Lower threshold for more concepts
1447
+ top_concepts.append({
1448
+ "concept": real_estate_concepts[i],
1449
+ "confidence": float(prob)
1450
+ })
1451
+
1452
+ # Analyze style patterns
1453
+ style_keywords = ["modern", "traditional", "contemporary", "luxury", "minimalist", "rustic", "industrial"]
1454
+ style_scores = {}
1455
+
1456
+ for style in style_keywords:
1457
+ style_score = sum(concept["confidence"] for concept in top_concepts if style in concept["concept"].lower())
1458
+ if style_score > 0:
1459
+ style_scores[style] = style_score
1460
+
1461
+ # Determine dominant style
1462
+ dominant_style = max(style_scores.items(), key=lambda x: x[1]) if style_scores else ("unknown", 0)
1463
+
1464
+ return {
1465
+ "scene_concepts": sorted(top_concepts, key=lambda x: x["confidence"], reverse=True)[:10],
1466
+ "style_analysis": {
1467
+ "dominant_style": dominant_style[0],
1468
+ "style_confidence": dominant_style[1],
1469
+ "all_style_scores": style_scores,
1470
+ "quality_indicators": [concept for concept in top_concepts if "quality" in concept["concept"].lower() or "premium" in concept["concept"].lower()],
1471
+ "functionality_indicators": [concept for concept in top_concepts if "functional" in concept["concept"].lower() or "efficient" in concept["concept"].lower()]
1472
+ }
1473
+ }
1474
+
1475
+ except Exception as e:
1476
+ logger.error(f"CLIP scene analysis failed: {str(e)}")
1477
+ return {'scene_concepts': [], 'style_analysis': {}}
1478
+
1479
+ def analyze_market_positioning(room_classification, quality_analysis, object_detection, property_assessment):
1480
+ """Advanced market positioning analysis"""
1481
+ try:
1482
+ market_analysis = {
1483
+ "market_tier": "Unknown",
1484
+ "competitive_position": "Unknown",
1485
+ "price_positioning": "Unknown",
1486
+ "target_market": "Unknown",
1487
+ "differentiation_factors": [],
1488
+ "market_opportunities": [],
1489
+ "competitive_advantages": [],
1490
+ "market_risks": []
1491
+ }
1492
+
1493
+ # Extract key metrics
1494
+ quality_score = quality_analysis.get('quality_score', 0)
1495
+ overall_score = property_assessment.get('overall_score', 0)
1496
+ room_type = room_classification.get('room_type', 'unknown')
1497
+ room_confidence = room_classification.get('confidence', 0)
1498
+ object_analysis = object_detection.get('analysis', {})
1499
+
1500
+ # 1. Market Tier Analysis
1501
+ if overall_score >= 85:
1502
+ market_analysis["market_tier"] = "Luxury"
1503
+ market_analysis["price_positioning"] = "Premium"
1504
+ market_analysis["target_market"] = "High-end buyers, investors"
1505
+ elif overall_score >= 75:
1506
+ market_analysis["market_tier"] = "Premium"
1507
+ market_analysis["price_positioning"] = "Above market"
1508
+ market_analysis["target_market"] = "Professional buyers, families"
1509
+ elif overall_score >= 60:
1510
+ market_analysis["market_tier"] = "Standard"
1511
+ market_analysis["price_positioning"] = "Market rate"
1512
+ market_analysis["target_market"] = "General buyers"
1513
+ else:
1514
+ market_analysis["market_tier"] = "Value"
1515
+ market_analysis["price_positioning"] = "Below market"
1516
+ market_analysis["target_market"] = "Budget-conscious buyers"
1517
+
1518
+ # 2. Competitive Position Analysis
1519
+ if quality_score >= 80 and room_confidence >= 80:
1520
+ market_analysis["competitive_position"] = "Strong"
1521
+ market_analysis["competitive_advantages"].append("High-quality presentation")
1522
+ market_analysis["competitive_advantages"].append("Clear room identification")
1523
+ elif quality_score >= 60 and room_confidence >= 60:
1524
+ market_analysis["competitive_position"] = "Competitive"
1525
+ market_analysis["competitive_advantages"].append("Good presentation quality")
1526
+ else:
1527
+ market_analysis["competitive_position"] = "Needs improvement"
1528
+ market_analysis["market_risks"].append("Poor presentation may limit appeal")
1529
+
1530
+ # 3. Room-specific positioning
1531
+ if room_type in ['kitchen', 'bathroom']:
1532
+ appliance_count = object_analysis.get('appliance_count', 0)
1533
+ fixture_count = object_analysis.get('fixture_count', 0)
1534
+
1535
+ if room_type == 'kitchen' and appliance_count >= 3:
1536
+ market_analysis["differentiation_factors"].append("Fully equipped kitchen")
1537
+ market_analysis["competitive_advantages"].append("Modern kitchen appliances")
1538
+ elif room_type == 'bathroom' and fixture_count >= 2:
1539
+ market_analysis["differentiation_factors"].append("Well-appointed bathroom")
1540
+ market_analysis["competitive_advantages"].append("Quality bathroom fixtures")
1541
+
1542
+ # 4. Object density analysis
1543
+ object_density = object_analysis.get('object_density', 0)
1544
+ if object_density > 10:
1545
+ market_analysis["differentiation_factors"].append("Rich content and features")
1546
+ market_analysis["competitive_advantages"].append("Well-appointed space")
1547
+ elif object_density < 3:
1548
+ market_analysis["market_risks"].append("Limited content may reduce appeal")
1549
+
1550
+ # 5. Market opportunities
1551
+ if quality_score < 70:
1552
+ market_analysis["market_opportunities"].append("Improve image quality for better positioning")
1553
+
1554
+ if room_confidence < 70:
1555
+ market_analysis["market_opportunities"].append("Enhance room type clarity")
1556
+
1557
+ if object_density < 5:
1558
+ market_analysis["market_opportunities"].append("Add more features and furniture")
1559
+
1560
+ # 6. Professional grade analysis
1561
+ if property_assessment.get('professional_grade', False):
1562
+ market_analysis["competitive_advantages"].append("Professional-grade presentation")
1563
+ market_analysis["differentiation_factors"].append("High-quality photography")
1564
+ else:
1565
+ market_analysis["market_opportunities"].append("Consider professional photography")
1566
+
1567
+ return market_analysis
1568
+
1569
+ except Exception as e:
1570
+ logger.error(f"Market positioning analysis failed: {str(e)}")
1571
+ return {
1572
+ "market_tier": "Unknown",
1573
+ "competitive_position": "Unknown",
1574
+ "price_positioning": "Unknown",
1575
+ "target_market": "Unknown",
1576
+ "differentiation_factors": [],
1577
+ "market_opportunities": [],
1578
+ "competitive_advantages": [],
1579
+ "market_risks": []
1580
+ }
1581
+
1582
+ def classify_room_type(image):
1583
+ """Classify room type using the loaded room classifier"""
1584
+ try:
1585
+ if room_classifier is None:
1586
+ return {'room_type': 'unknown', 'confidence': 0}
1587
+
1588
+ results = room_classifier(image)
1589
+ return {
1590
+ 'room_type': results[0]['label'].lower(),
1591
+ 'confidence': round(results[0]['score'] * 100, 2)
1592
+ }
1593
+ except Exception as e:
1594
+ logger.error(f"Room classification failed: {str(e)}")
1595
+ return {'room_type': 'unknown', 'confidence': 0}
1596
+
1597
  @app.route('/')
1598
  def index():
1599
  """Main page for the image analyzer"""
1600
+ return render_template('analyzeindex.html')
1601
 
1602
  @app.route('/analyze', methods=['POST'])
1603
  def analyze_image():
 
1765
  }
1766
  })
1767
 
1768
+ @app.route('/debug')
1769
+ def debug_info():
1770
+ """Debug endpoint to check application status"""
1771
+ return jsonify({
1772
+ 'status': 'running',
1773
+ 'port': os.environ.get('PORT', 7860),
1774
+ 'models_loaded': {
1775
+ 'room_classifier': room_classifier is not None,
1776
+ 'image_captioner': image_captioner is not None,
1777
+ 'yolo_model': yolo_model is not None,
1778
+ 'clip_processor': clip_processor is not None,
1779
+ 'clip_model': clip_model is not None
1780
+ },
1781
+ 'python_version': sys.version,
1782
+ 'torch_available': torch.cuda.is_available() if torch.cuda.is_available() else 'CPU only',
1783
+ 'timestamp': datetime.now().isoformat()
1784
+ })
1785
+
1786
  @app.route('/static/<path:filename>')
1787
  def static_files(filename):
1788
  """Serve static files"""